fast_xlsx 0.8.0 → 0.8.1
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 +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +1 -1
- data/bench/Gemfile.lock +2 -2
- data/ext/fast_xlsx/Cargo.toml +1 -1
- data/ext/fast_xlsx/src/lib.rs +33 -3
- data/lib/fast_xlsx/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f530f027eb2e902f4bed36fdfd75af2851ff93a9762915a56f9de3e966eab593
|
|
4
|
+
data.tar.gz: 794ddb87412acfa82840681a9caf32f85eb0d5b47fc0921c7091f3bbde020677
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 915d233e6c422187d23853c1c521bdefbf3336d85af03574882dc14a8055b1f692e3044588281c33c94e451be5123f516c4b07e2596111782c2b2a1f68fa261a
|
|
7
|
+
data.tar.gz: 98aa0c5de0d29816828a8fe6215c5132b7bd88297ed13bf6db9df9ddd6f0221e27f7a804a082e4430daffbb235193f1c85ffb898f41f6fee94940625d0caabb2
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.8.1] - 2026-10-03
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Rails' `ActiveSupport::TimeWithZone` (e.g. `created_at`) and other objects that act like a `Time` without being one were written as text; they are dates now.
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Writing `Time` values is about 25% faster (read through Ruby's C API instead of method calls), and `Date` values a little faster.
|
|
12
|
+
|
|
3
13
|
## [0.8.0] - 2026-10-02
|
|
4
14
|
|
|
5
15
|
### Changed
|
data/README.md
CHANGED
|
@@ -370,7 +370,7 @@ Values are mapped by type:
|
|
|
370
370
|
|---|---|
|
|
371
371
|
| `Integer`, `Float`, any `Numeric` | number |
|
|
372
372
|
| `String` | string |
|
|
373
|
-
| `Time`, `DateTime` | date and time (`yyyy-mm-dd hh:mm:ss` unless formatted), in its own offset |
|
|
373
|
+
| `Time`, `DateTime`, time-like objects such as Rails' `ActiveSupport::TimeWithZone` | date and time (`yyyy-mm-dd hh:mm:ss` unless formatted), in its own offset |
|
|
374
374
|
| `Date` | date (`yyyy-mm-dd` unless formatted) |
|
|
375
375
|
| `FastXlsx::Formula.new("SUM(A1:A9)")` | formula |
|
|
376
376
|
| `FastXlsx::URL.new("https://…")`, `URL.new(url, text: "Title")` | hyperlink (optionally showing other text) |
|
data/bench/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
fast_xlsx (0.8.
|
|
4
|
+
fast_xlsx (0.8.1)
|
|
5
5
|
rb_sys (~> 0.9.130)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -77,7 +77,7 @@ DEPENDENCIES
|
|
|
77
77
|
CHECKSUMS
|
|
78
78
|
caxlsx (4.5.0) sha256=e3d98d859f148df05d5462086b5079b523f29c1766b569535f1d68629ce743ff
|
|
79
79
|
fast_excel (0.5.0) sha256=59c418bdcf586a6030798d4e3a9f575742badaceaf7bb90f38eee5feb5bdc478
|
|
80
|
-
fast_xlsx (0.8.
|
|
80
|
+
fast_xlsx (0.8.1)
|
|
81
81
|
ffi (1.17.4-aarch64-linux-gnu) sha256=b208f06f91ffd8f5e1193da3cae3d2ccfc27fc36fba577baf698d26d91c080df
|
|
82
82
|
ffi (1.17.4-aarch64-linux-musl) sha256=9286b7a615f2676245283aef0a0a3b475ae3aae2bb5448baace630bb77b91f39
|
|
83
83
|
ffi (1.17.4-arm-linux-gnu) sha256=d6dbddf7cb77bf955411af5f187a65b8cd378cb003c15c05697f5feee1cb1564
|
data/ext/fast_xlsx/Cargo.toml
CHANGED
|
@@ -10,7 +10,7 @@ publish = false
|
|
|
10
10
|
crate-type = ["cdylib"]
|
|
11
11
|
|
|
12
12
|
[dependencies]
|
|
13
|
-
magnus = "0.9"
|
|
13
|
+
magnus = { version = "0.9", features = ["rb-sys"] }
|
|
14
14
|
rb-sys = { version = "0.9", features = ["stable-api-compiled-fallback"] }
|
|
15
15
|
# No "zlib" feature: without it zip compresses with zlib-rs, which saves
|
|
16
16
|
# 20-30% faster than the system zlib (and needs no C library).
|
data/ext/fast_xlsx/src/lib.rs
CHANGED
|
@@ -328,7 +328,29 @@ fn excel_serial(days: f64) -> Result<f64, Error> {
|
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
// Time: seconds since 1970-01-01 (serial day 25569), in its own offset.
|
|
331
|
+
// For a Time (checked by the caller): Ruby's C functions, with no method calls,
|
|
332
|
+
// since this runs once per cell.
|
|
331
333
|
fn excel_time(v: Value) -> Result<f64, Error> {
|
|
334
|
+
use magnus::rb_sys::{protect, AsRawValue, FromRawValue};
|
|
335
|
+
// Both can raise (a Time out of range or uninitialized, or a zone object
|
|
336
|
+
// whose Ruby code fails), so they run under protect: a raise becomes an
|
|
337
|
+
// Err instead of a longjmp over these Rust frames.
|
|
338
|
+
let mut spec = None;
|
|
339
|
+
protect(|| {
|
|
340
|
+
// SAFETY: protect catches anything this raises.
|
|
341
|
+
spec = Some(unsafe { rb_sys::rb_time_timespec(v.as_raw()) });
|
|
342
|
+
rb_sys::Qnil as rb_sys::VALUE
|
|
343
|
+
})?;
|
|
344
|
+
// SAFETY: as above.
|
|
345
|
+
let offset = protect(|| unsafe { rb_sys::rb_time_utc_offset(v.as_raw()) })?;
|
|
346
|
+
let (spec, offset) = (spec.unwrap(), unsafe { Value::from_raw(offset) });
|
|
347
|
+
let secs = spec.tv_sec as f64 + spec.tv_nsec as f64 / 1e9;
|
|
348
|
+
excel_serial((secs + i64::try_convert(offset)? as f64) / 86400.0 + 25569.0)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Something that acts like a Time without being one at the C level, such as
|
|
352
|
+
// Rails' ActiveSupport::TimeWithZone (it delegates to a Time).
|
|
353
|
+
fn excel_time_like(v: Value) -> Result<f64, Error> {
|
|
332
354
|
let secs: f64 = v.funcall("to_f", ())?;
|
|
333
355
|
let offset: i64 = v.funcall("utc_offset", ())?;
|
|
334
356
|
excel_serial((secs + offset as f64) / 86400.0 + 25569.0)
|
|
@@ -336,9 +358,14 @@ fn excel_time(v: Value) -> Result<f64, Error> {
|
|
|
336
358
|
|
|
337
359
|
// Date / DateTime: Julian day and day fraction are both in the object's own
|
|
338
360
|
// offset. JD 2415019 is 1899-12-30.
|
|
339
|
-
|
|
361
|
+
// `time`: a DateTime, with a time of day; a Date's day fraction is always 0.
|
|
362
|
+
fn excel_date(v: Value, time: bool) -> Result<f64, Error> {
|
|
340
363
|
let jd: i64 = v.funcall("jd", ())?;
|
|
341
|
-
let fraction
|
|
364
|
+
let fraction = if time {
|
|
365
|
+
f64::try_convert(v.funcall("day_fraction", ())?)?
|
|
366
|
+
} else {
|
|
367
|
+
0.0
|
|
368
|
+
};
|
|
342
369
|
excel_serial((jd - 2_415_019) as f64 + fraction)
|
|
343
370
|
}
|
|
344
371
|
|
|
@@ -413,7 +440,10 @@ impl CellValue {
|
|
|
413
440
|
CellValue::Rich(parts)
|
|
414
441
|
} else if v.respond_to("jd", false)? {
|
|
415
442
|
// Date has no #hour; DateTime does.
|
|
416
|
-
|
|
443
|
+
let time = v.respond_to("hour", false)?;
|
|
444
|
+
CellValue::Date(excel_date(v, time)?, time)
|
|
445
|
+
} else if v.respond_to("utc_offset", false)? && v.respond_to("to_f", false)? {
|
|
446
|
+
CellValue::Date(excel_time_like(v)?, true)
|
|
417
447
|
} else {
|
|
418
448
|
CellValue::Text(v.funcall("to_s", ())?)
|
|
419
449
|
};
|
data/lib/fast_xlsx/version.rb
CHANGED