zlight_csv 0.4.0-x86_64-linux → 0.6.0-x86_64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b96428d44c1acb33466a227063e7318cdfdd4233464f533a832accac4e0abf4
4
- data.tar.gz: 633c2c530b5ddfd75dc1e006ba345e253c1f4f41e503f0094575421e6d92375f
3
+ metadata.gz: 4b9429002bef342c43edd29b084d759f6b2609e77295f7af997f47e783a39eea
4
+ data.tar.gz: 5216c05e5db7d8011cb4afa85505599a6c460b93537d521d6a47a352ee158f5e
5
5
  SHA512:
6
- metadata.gz: 89b7b97b16cbae21d906f990cf5440ebb3438e403e0a20f02dda8a13a5c302e868de5e5d649e97c362623dbde050c225eea28ad20c424a511ed883d3fcc22d7b
7
- data.tar.gz: f164fd92db98090061b241cb81da26fb9fda646d244d6d63afac992f5bfcc66f059aefb1e499883ce446d995f3e5597af3c927b8882043462f695b3e116495c1
6
+ metadata.gz: d67d65564a2910eb4e2b06d9666c8db4d8e95a6da610458941a78e58f77db7681fd8a1ed3c37a7c797a2661ae19d4ffe5d47917f8ac08d7fa98f2aea7e6017e1
7
+ data.tar.gz: 24dd4e179f55d42683892c572313388840143c2eeeed32d10cf7a15589596b13cd71ee9c9440a67e55deac6029ee272d5df06748530d239ff26d1ae55a22be43
data/ARCHITECTURE.md ADDED
@@ -0,0 +1,132 @@
1
+ # Architecture
2
+
3
+ This is a guide for changing the code, written on the assumption that you know
4
+ Ruby or Python and may not know Rust. You do not need to read Rust fluently to
5
+ find your way around — the layout is designed so that a given change lives in
6
+ one predictable place.
7
+
8
+ ## The short version
9
+
10
+ ZLight is a **Ruby gem with its hot loop written in Rust**. Ruby handles the
11
+ public API and file conveniences; Rust does the parsing and writing.
12
+
13
+ ```
14
+ your code
15
+
16
+
17
+ lib/zlight_csv.rb Ruby: the public API
18
+ │ read / write / foreach / open are plain Ruby
19
+ │ parse / generate / stream / stream_file are not —
20
+ ▼ they are implemented in Rust
21
+ ext/zlight_csv/src/ Rust: the parser, the writer, the streaming reader
22
+
23
+
24
+ the `csv` crate the actual CSV state machine
25
+ ```
26
+
27
+ The `magnus` crate is the bridge: it is what lets Rust define a module Ruby can
28
+ call and build Ruby objects (`Hash`, `Array`, `String`) from Rust data.
29
+
30
+ ## Which file does what
31
+
32
+ ### Ruby side — `lib/`
33
+
34
+ | File | Owns |
35
+ |---|---|
36
+ | `zlight_csv.rb` | the public API and its documentation |
37
+ | `zlight_csv/native.rb` | loading the compiled library |
38
+ | `zlight_csv/errors.rb` | the exception hierarchy |
39
+ | `zlight_csv/version.rb` | the version, read from the `VERSION` file |
40
+
41
+ `native.rb` is worth understanding once. A compiled extension is built against
42
+ one specific Ruby version's internals, so a precompiled gem ships **one library
43
+ per Ruby minor version**:
44
+
45
+ ```
46
+ lib/zlight_csv/3.1/zlight_csv.so
47
+ lib/zlight_csv/3.4/zlight_csv.so
48
+ ```
49
+
50
+ `native.rb` picks the right one at load time. A gem built from source has a
51
+ single library instead, which is the fallback path.
52
+
53
+ ### Rust side — `ext/zlight_csv/src/`
54
+
55
+ | File | Owns | Analogy |
56
+ |---|---|---|
57
+ | `lib.rs` | the list of what Ruby can call | a routes file |
58
+ | `options.rs` | keyword arguments → typed settings | parsing params |
59
+ | `convert.rs` | one field → one Ruby value | a type coercer |
60
+ | `row.rs` | one record → one Ruby row | a serializer |
61
+ | `reader.rs` | building the CSV reader | a factory |
62
+ | `read/eager.rs` | `ZLight.parse` | |
63
+ | `read/stream.rs` | `ZLight::StreamReader` | |
64
+ | `write/mod.rs` | `ZLight.generate` | |
65
+ | `error.rs` | Rust errors → Ruby exceptions | an error handler |
66
+
67
+ The important structural point: **both read paths sit on the same three
68
+ helpers.** `read/eager.rs` and `read/stream.rs` differ only in *when* they read
69
+ — all at once, or a row at a time — and both build their reader with
70
+ `reader.rs`, convert fields with `convert.rs`, and shape rows with `row.rs`.
71
+ That is what stops the two from drifting apart.
72
+
73
+ ## Where to put a change
74
+
75
+ | You want to… | Change | Why there |
76
+ |---|---|---|
77
+ | add a field type (dates, booleans, a Ruby proc) | `convert.rs` + one arm in `options.rs` | `Converter` is the only thing that turns bytes into values |
78
+ | change what a row looks like (a Row object, a struct) | `row.rs` | `RowShape` is the only thing that builds rows |
79
+ | add a parse or write option | `options.rs` | both readers and the writer read their settings from here |
80
+ | add a whole new Ruby method | a file under `read/` or `write/`, plus one line in `lib.rs` | `lib.rs` is the complete list of the public surface |
81
+ | change an error's Ruby class | `error.rs` | one table maps every Rust error to a Ruby class |
82
+
83
+ If a change seems to require editing two files that do the same kind of work,
84
+ that is a sign the seam is in the wrong place — say so rather than copying the
85
+ code.
86
+
87
+ ## Two ideas that are easy to miss
88
+
89
+ **Conversion is a value, not a flag.** `Converter` is an enum — think of it as
90
+ a small sealed class hierarchy. It used to be a boolean (`convert_numeric`)
91
+ threaded through every function, which meant a second converter could not be
92
+ added without changing every signature it passed through. Now adding one is a
93
+ new variant plus an arm in `options.rs`.
94
+
95
+ **Row shape is a value too.** `RowShape` is either `Hashes(headers)` or
96
+ `Arrays`. Deciding once, up front, means the per-row code does not re-ask "do
97
+ we have headers?" for every row, and there is exactly one place that knows how
98
+ a row is built.
99
+
100
+ ## Working on it
101
+
102
+ You do not need Ruby or Rust installed on your machine — everything runs in
103
+ containers:
104
+
105
+ ```bash
106
+ ./docker/test-matrix.sh # every supported Ruby, 3.1 through 4.0
107
+ ./docker/test-matrix.sh 3.4 # just one
108
+ ```
109
+
110
+ With a local Ruby (3.1–4.0) and a Rust toolchain:
111
+
112
+ ```bash
113
+ bundle install
114
+ bundle exec rake compile # build the extension
115
+ bundle exec rake spec # run the suite
116
+ bundle exec rake clobber # remove every build artifact, cargo cache included
117
+ ```
118
+
119
+ `rake compile` must be re-run after any change under `ext/`. Ruby-only changes
120
+ take effect immediately.
121
+
122
+ ## The rule the tests enforce
123
+
124
+ The RSpec suite is the contract. A refactor that changes behaviour will fail
125
+ it; a refactor that does not, will not. If you find yourself editing a spec to
126
+ make a refactor pass, you are changing behaviour — stop and decide whether you
127
+ meant to.
128
+
129
+ Several examples deliberately pin places where ZLight **differs** from Ruby's
130
+ stdlib CSV (duplicate headers, empty fields, numeric edge cases). They assert
131
+ both sides on purpose, so the documented differences and the code cannot drift
132
+ apart. See the "Differences from stdlib CSV" section of the README.
data/CHANGELOG.md CHANGED
@@ -7,22 +7,159 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ## [0.1.0] - 2024-XX-XX
10
+ ## [0.6.0] - 2026-09-12
11
+
12
+ ### Added
13
+
14
+ - Custom converters. `converters:` now accepts any object answering `call`, a
15
+ built-in name, or an Array mixing the two, applied left to right:
16
+
17
+ ```ruby
18
+ ZLight.parse(csv, converters: ->(field) { field.strip })
19
+ ZLight.parse(csv, converters: [->(f) { f.strip }, :numeric])
20
+ ```
21
+
22
+ Semantics match Ruby's CSV, including that the chain stops as soon as a
23
+ converter returns something other than a String, and that converters are
24
+ never applied to the header row. An unusable converter raises ArgumentError
25
+ naming the problem, where Ruby's CSV raises NoMethodError from inside itself.
26
+
27
+ A converter must not read from or close the reader it is converting for, and
28
+ a reader running a converter must not be used from another thread. Either
29
+ raises `ZLight::Error` rather than corrupting a row. `ZLight.parse` is safe
30
+ from any thread, with or without a converter; Ractors are refused by Ruby.
31
+
32
+ ### Changed
33
+
34
+ - The extension is organised around three seams — field conversion, row shape
35
+ and reader construction — each owned by one file and shared by both read
36
+ paths, so a feature is added in one place rather than two. See
37
+ ARCHITECTURE.md
38
+ - Removed comments that restated the code they sat above, keeping those that
39
+ explain a decision, an invariant, or where new code belongs
40
+
41
+ ### Fixed
42
+
43
+ - The documentation for `parse`, `generate` and `StreamReader` was attached to
44
+ no method, so YARD rendered none of it
45
+
46
+ ## [0.5.1] - 2026-09-12
47
+
48
+ ### Fixed
49
+
50
+ - The extension now builds against a Ruby that rb-sys has no prebuilt bindings
51
+ for, via rb-sys `stable-api-compiled-fallback`, rather than failing outright.
52
+ This is the mechanism that breaks the build on every new Ruby release until
53
+ rb-sys catches up
54
+ - Windows CI could not build the extension at all: the runner paired a MinGW
55
+ Ruby with an MSVC Rust toolchain. Ruby and Rust are now set up together so
56
+ their ABIs match, and Windows is verified across Ruby 3.1-4.0
57
+ - Specs that asserted Unix-only error messages and paths now pass on Windows
58
+ - Dropped an unreachable credentials check from the release workflow: the
59
+ credentials action fails first, so the check never ran
60
+
61
+ ### Note
62
+
63
+ - 0.5.0 was tagged but never reached RubyGems: its release run built every gem
64
+ and then failed to publish, because trusted publishing still named the
65
+ project's former GitHub account. 0.5.1 is the first release carrying the
66
+ 0.5.0 changes below.
67
+
68
+ ## [0.5.0] - 2026-09-12
69
+
70
+ ### Added
71
+
72
+ - Ruby 4.0 support
73
+ - `docker/test-matrix.sh`, which builds and tests the extension against every
74
+ supported Ruby in containers
75
+ - Windows, Ruby 4.0 and a `ruby-head` early-warning job in CI, plus weekly
76
+ scheduled runs and Dependabot
77
+
78
+ ### Changed
79
+
80
+ - Upgraded magnus from 0.6 to 0.8. magnus 0.6 read a field of Ruby's
81
+ RTypedData struct that Ruby 4.0 removed, so the extension could not compile
82
+ against it at all
83
+ - Minimum Ruby is now 3.1. Ruby 3.0 is end-of-life and no longer supported by
84
+ magnus
85
+ - Repository URLs now point at `codebyisaad/zlight`, which is where the code
86
+ is hosted
87
+
88
+ ### Fixed
89
+
90
+ - The source gem shipped no extension and could not be compiled, so any Ruby
91
+ or platform without a prebuilt binary installed a gem that failed to load
92
+ - `ZLight::ParseError`, `ZLight::EncodingError` and `ZLight::StreamClosedError`
93
+ were documented but never raised
94
+ - Integers outside the i64 range were silently converted to lossy Floats
95
+ - `col_sep` and `quote_char` longer than one byte were silently truncated when
96
+ reading, while writing rejected them
97
+ - Releases no longer yank every previously published version
98
+
99
+
100
+ ## [0.4.0] - 2026-06-06
101
+
102
+ ### Added
103
+
104
+ - `ZLight.generate` — build a CSV string from an array of hashes or an array
105
+ of arrays, with `headers`, `col_sep`, `quote_char` and `force_quotes` options
106
+ - `ZLight.write` — generate a CSV and write it to a file in one call
107
+
108
+ ### Changed
109
+
110
+ - Parsed fields are tagged with the encoding of the input string, matching
111
+ Ruby's stdlib CSV, so the parser and writer round-trip without
112
+ `force_encoding`
113
+
114
+ ## [0.3.0] - 2026-05-21
115
+
116
+ ### Changed
117
+
118
+ - Release pipeline updates
119
+
120
+ ## [0.2.5] - 2026-05-21
121
+
122
+ ### Added
123
+
124
+ - `ZLight.stream` and `ZLight.stream_file` — read rows one at a time without
125
+ loading the whole input into memory
126
+ - `ZLight.open` — streaming with a block, closing the reader automatically
127
+ - `ZLight::StreamReader`, including `Enumerable`, so `lazy`, `select`, `find`
128
+ and friends work over a stream
129
+
130
+ ### Fixed
131
+
132
+ - Packaging and gemspec metadata corrections across 0.2.1–0.2.5
133
+
134
+ ## [0.2.0] - 2026-05-21
135
+
136
+ ### Added
137
+
138
+ - Benchmark suite comparing ZLight against Ruby's stdlib CSV
139
+ - Edge case coverage for quoting, encodings and flexible records
140
+
141
+ ## [0.1.2] - 2026-05-19
11
142
 
12
143
  ### Added
13
144
 
14
145
  - Initial release
15
- - `Zlight::Csv.parse` - Parse CSV strings with optional headers and numeric conversion
16
- - `Zlight::Csv.read` - Read and parse CSV files
17
- - `Zlight::Csv.foreach` - Iterate over CSV rows
18
- - `Zlight.parse` and `Zlight.read` convenience methods
19
- - Support for custom delimiters (`col_sep`)
20
- - Support for custom quote characters (`quote_char`)
21
- - Flexible record length support
22
- - Enum-based error handling with descriptive messages
23
- - Cross-platform native gem builds
146
+ - `ZLight.parse` parse CSV strings, with `headers`, `converters`, `col_sep`,
147
+ `quote_char` and `flexible` options
148
+ - `ZLight.read` read and parse a CSV file
149
+ - `ZLight.foreach` iterate over parsed rows
150
+ - Cross-platform precompiled native gems
24
151
 
25
152
  ### Performance
26
153
 
27
- - Up to 10x faster than Ruby's standard CSV library
28
- - Efficient memory usage through Rust's zero-copy parsing
154
+ - Substantially faster than Ruby's stdlib CSV; see the README for measured
155
+ figures
156
+
157
+ [Unreleased]: https://github.com/codebyisaad/zlight/compare/v0.6.0...HEAD
158
+ [0.6.0]: https://github.com/codebyisaad/zlight/compare/v0.5.1...v0.6.0
159
+ [0.5.1]: https://github.com/codebyisaad/zlight/compare/v0.5.0...v0.5.1
160
+ [0.5.0]: https://github.com/codebyisaad/zlight/compare/v0.4.0...v0.5.0
161
+ [0.4.0]: https://github.com/codebyisaad/zlight/compare/v0.3.0...v0.4.0
162
+ [0.3.0]: https://github.com/codebyisaad/zlight/compare/v0.2.5...v0.3.0
163
+ [0.2.5]: https://github.com/codebyisaad/zlight/compare/v0.2.0...v0.2.5
164
+ [0.2.0]: https://github.com/codebyisaad/zlight/compare/v0.1.2...v0.2.0
165
+ [0.1.2]: https://github.com/codebyisaad/zlight/releases/tag/v0.1.2
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Zaidan Chaudhary
3
+ Copyright (c) 2024 Zaidan Chaudhary (also known as Saad Chaudhary)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -7,7 +7,8 @@ A fast CSV parser for Ruby, powered by Rust.
7
7
 
8
8
  ## Why ZLight?
9
9
 
10
- Ruby's built-in CSV library is slow. ZLight parses CSV files **up to 30x faster** by using Rust under the hood.
10
+ Ruby's built-in CSV library is slow. ZLight parses CSV files **up to 40x faster** by using Rust under the hood.
11
+ The gap is widest on small inputs and narrows as they grow; the measurements below show the range.
11
12
 
12
13
  ### Benchmark Results
13
14
 
@@ -102,12 +103,64 @@ ZLight.parse (full): 73ms
102
103
  ZLight.stream (lazy): 0.3ms ← 5,600x faster!
103
104
  ```
104
105
 
106
+ ### Custom Converters
107
+
108
+ `converters:` takes a built-in name, any object answering `call`, or an Array
109
+ of them applied left to right:
110
+
111
+ ```ruby
112
+ # A single callable, given each field as a String
113
+ ZLight.parse(csv, converters: ->(field) { field.strip })
114
+
115
+ # Chained: trim, then recognise numbers
116
+ ZLight.parse(csv, converters: [->(f) { f.strip }, :numeric])
117
+
118
+ # Anything answering #call works
119
+ ZLight.parse(csv, converters: MyConverter.new)
120
+ ```
121
+
122
+ Two rules, both matching Ruby's CSV:
123
+
124
+ - **The chain stops** as soon as a converter returns something other than a
125
+ String, so `[:numeric, other]` never calls `other` for a field that was
126
+ converted to a number.
127
+ - **Converters never apply to the header row.** Headers are always symbols.
128
+
129
+ An exception raised inside a converter propagates to the caller. A converter
130
+ that is neither a known name nor callable raises `ArgumentError` naming the
131
+ problem.
132
+
133
+ A converter must not use the reader it is converting for — calling `next_row`,
134
+ `headers` or `close` on it raises `ZLight::Error`. Any other reader, and
135
+ `ZLight.parse` itself, are fine:
136
+
137
+ ```ruby
138
+ # Raises ZLight::Error
139
+ reader = ZLight.stream(csv, converters: ->(f) { reader.next_row })
140
+
141
+ # Fine
142
+ ZLight.parse(csv, converters: ->(f) { ZLight.parse(lookup_csv).first[:name] })
143
+ ```
144
+
145
+ ### Threads and Ractors
146
+
147
+ | | |
148
+ |---|---|
149
+ | `ZLight.parse`, `.generate`, `.read`, `.write` | safe from any thread |
150
+ | A `StreamReader` shared between threads | safe while no converter is running |
151
+ | A `StreamReader` shared between threads, with a converter | raises `ZLight::Error` |
152
+ | Ractors | not supported; Ruby refuses to cross the boundary |
153
+
154
+ A converter runs Ruby code, which lets another thread take the GVL mid-row. The
155
+ reader refuses that rather than returning a corrupted row. **Give each thread
156
+ its own reader** and the question does not arise.
157
+
105
158
  ### Options (Reading)
106
159
 
107
160
  | Option | Default | Description |
108
161
  |--------|---------|-------------|
109
162
  | `headers` | `true` | Use first row as headers (returns hashes). Set `false` for arrays. |
110
- | `converters` | `nil` | Set to `:numeric` to convert numbers automatically |
163
+ | `converters` | `nil` | `:numeric`, any object answering `call`, or an Array of them |
111
164
  | `col_sep` | `","` | Column separator (`"\t"` for TSV, `";"` for European CSV) |
112
165
  | `quote_char` | `"` | Quote character |
113
166
  | `flexible` | `true` | Allow rows with varying column counts |
@@ -156,21 +209,70 @@ CSV.parse(data, headers: true, header_converters: :symbol, converters: :numeric)
156
209
  ZLight.parse(data, converters: :numeric)
157
210
  ```
158
211
 
212
+ ### Differences from stdlib CSV
213
+
214
+ ZLight is not a complete reimplementation of `CSV`. The differences below are
215
+ deliberate, and are the ones most likely to matter when migrating.
216
+
217
+ **API shape**
218
+
219
+ - `ZLight.foreach` takes a **CSV string**, while `CSV.foreach` takes a **file
220
+ path**. Use `ZLight.open` to iterate a file.
221
+ - `ZLight.foreach` parses the whole input before yielding. For genuinely lazy
222
+ iteration use `ZLight.stream` or `ZLight.open`.
223
+ - `ZLight::StreamReader` is single-pass. It includes `Enumerable`, but each
224
+ row is consumed as it is read, so a second pass yields nothing and there is
225
+ no rewind. Call `ZLight.stream` again to re-read.
226
+
227
+ **Parsing**
228
+
229
+ - Duplicate headers collapse. Rows are `Hash`es, so `"a,a"` keeps only the
230
+ last `:a` column; `CSV` keeps both.
231
+ - Fields beyond the header count are dropped rather than collected.
232
+ - Headers become symbols always, equivalent to `header_converters: :symbol`.
233
+
234
+ **`converters: :numeric`**
235
+
236
+ | Input | ZLight | Ruby CSV |
237
+ |--------------|-------------------|------------|
238
+ | `""` | `""` | `nil` |
239
+ | `"0x10"` | `"0x10"` | `16` |
240
+ | `"1_000"` | `"1_000"` | `1000` |
241
+ | `"Infinity"` | `Float::INFINITY` | `"Infinity"` |
242
+ | `"NaN"` | `Float::NAN` | `"NaN"` |
243
+
244
+ Integers of any size are exact, as in `CSV`.
245
+
246
+ **Writing**
247
+
248
+ - `ZLight.generate` takes its column order from the keys of the **first**
249
+ hash. Keys that appear only in later rows are not written; keys missing
250
+ from a later row are written as empty fields.
251
+
159
252
  ## Requirements
160
253
 
161
- - Ruby 3.0+
254
+ - Ruby 3.1 or newer, including Ruby 4.0
162
255
  - Linux (x86_64, aarch64), macOS (Intel, Apple Silicon), or Windows (x64)
163
256
 
257
+ Every supported Ruby is built and tested on each change; see
258
+ `docker/test-matrix.sh` to run that matrix yourself. Rubies without a
259
+ precompiled binary install from the source gem and need a Rust toolchain.
260
+
164
261
  ## Roadmap
165
262
 
166
263
  - [x] Streaming/lazy parsing for large files
167
264
  - [x] CSV writing support
168
- - [ ] Custom converter procs
265
+ - [x] Custom converter procs
266
+ - [ ] Streaming writer for large output
169
267
 
170
268
  ## Contributing
171
269
 
172
- Bug reports and pull requests are welcome on [GitHub](https://github.com/zaidanch/zlight).
270
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/codebyisaad/zlight).
271
+
272
+ ## Author
273
+
274
+ Zaidan Chaudhary, who also publishes as Saad Chaudhary.
173
275
 
174
276
  ## License
175
277
 
176
- MIT
278
+ MIT. See [LICENSE](LICENSE).
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.6.0
@@ -0,0 +1,30 @@
1
+ [package]
2
+ name = "zlight_csv"
3
+ # Synced from ../../VERSION by extconf.rb — do not edit manually.
4
+ version = "0.6.0"
5
+ edition = "2021"
6
+ authors = ["Zaidan Chaudhary", "Saad Chaudhary"]
7
+ description = "High-performance CSV parser for Ruby, powered by Rust"
8
+ license = "MIT"
9
+ repository = "https://github.com/codebyisaad/zlight"
10
+
11
+ [lib]
12
+ crate-type = ["cdylib"]
13
+ path = "src/lib.rs"
14
+
15
+ [dependencies]
16
+ csv = "1"
17
+ magnus = "0.8"
18
+ # Depended on directly, only to turn on stable-api-compiled-fallback.
19
+ # rb-sys ships prebuilt bindings for Ruby versions it knows about and fails
20
+ # outright on ones it does not, which is what breaks the build on every new
21
+ # Ruby before rb-sys catches up. The fallback compiles the shim from the
22
+ # headers of whatever Ruby is present instead, so an unreleased Ruby builds.
23
+ rb-sys = { version = "0.9", features = ["stable-api-compiled-fallback"] }
24
+ thiserror = "1"
25
+
26
+ [profile.release]
27
+ lto = true
28
+ codegen-units = 1
29
+ opt-level = 3
30
+ strip = true
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mkmf"
4
+ require "rb_sys/mkmf"
5
+
6
+ def sync_cargo_version!
7
+ version = File.read(File.expand_path("../../VERSION", __dir__), encoding: "UTF-8").strip
8
+ cargo_toml = File.join(__dir__, "Cargo.toml")
9
+ contents = File.read(cargo_toml, encoding: "UTF-8")
10
+ updated = contents.sub(/^version = ".*"$/, %(version = "#{version}"))
11
+ File.write(cargo_toml, updated) if contents != updated
12
+ end
13
+
14
+ sync_cargo_version!
15
+
16
+ create_rust_makefile("zlight_csv/zlight_csv")