Commit graph

519 commits

Author SHA1 Message Date
Andrew Gallant
61dc9bd8aa fmt: rename Decimal to Integer
Some checks failed
ci / win-msvc (push) Has been cancelled
ci / win-gnu (push) Has been cancelled
ci / msrv (push) Has been cancelled
ci / examples (push) Has been cancelled
ci / test-all (macos, macos-latest, nightly) (push) Has been cancelled
ci / test-default (beta, ubuntu-latest, beta) (push) Has been cancelled
ci / test-default (macos, macos-latest, stable) (push) Has been cancelled
ci / test-default (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-default (stable, ubuntu-latest, stable) (push) Has been cancelled
ci / test-all (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-only-bundle (macos, macos-latest, nightly) (push) Has been cancelled
ci / test-only-bundle (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-core (macos, macos-latest, nightly) (push) Has been cancelled
ci / test-core (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-various-feature-combos (macos, macos-latest, nightly) (push) Has been cancelled
ci / test-various-feature-combos (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / cross (aarch64-linux-android) (push) Has been cancelled
ci / cross (aarch64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (i686-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (s390x-unknown-linux-gnu) (push) Has been cancelled
ci / cross (x86_64-linux-android) (push) Has been cancelled
ci / riscv32imc-unknown-none-elf (push) Has been cancelled
ci / wasm32-wasip1 (push) Has been cancelled
ci / wasm32-unknown-emscripten (push) Has been cancelled
ci / wasm32-unknown-uknown (push) Has been cancelled
ci / docsrs (push) Has been cancelled
ci / rustfmt (push) Has been cancelled
ci / generated (push) Has been cancelled
And similarly for `DecimalFormatter`.

I believe I originally called this `Decimal` because it was also used to
do fractional formatting.
2025-12-22 21:02:40 -05:00
Andrew Gallant
1467f47e36 fmt: get rid of Decimal::end
It's not used. I believe it was being used when `Decimal` was also
responsible for formatting the fractional part of a floating point
number. But it isn't needed any more.
2025-12-22 21:02:40 -05:00
Andrew Gallant
5b27b22096 fmt: simplify decimal formatter
I don't think we need to keep track of maximum digits separately for
signed and unsigned integer formatting. I think this might mean that
signed integer formatting uses an extra byte of stack space, but, it can
also have a sign. Unlike unsigned integer formatting. So no space is
wasted here.

We also remove the `force_sign` option, which Jiff does not use. And
overall simplify the signed integer formatting to just reuse the
unsigned integer formatting. And also get rid of the dumb
`checked_abs()` usage. Not sure what I was thinking.
2025-12-22 21:02:40 -05:00
Andrew Gallant
4d2041567c binary-size: remove many uses of write!
Some checks are pending
ci / msrv (push) Waiting to run
ci / examples (push) Waiting to run
ci / test-various-feature-combos (macos, macos-latest, nightly) (push) Waiting to run
ci / integrations (push) Waiting to run
ci / time-zone-init (macos-latest) (push) Waiting to run
ci / test-various-feature-combos (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / time-zone-init (ubuntu-24.04-arm) (push) Waiting to run
ci / test-default (beta, ubuntu-latest, beta) (push) Waiting to run
ci / test-default (macos, macos-latest, stable) (push) Waiting to run
ci / test-default (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-default (stable, ubuntu-latest, stable) (push) Waiting to run
ci / test-all (macos, macos-latest, nightly) (push) Waiting to run
ci / test-all (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-only-bundle (macos, macos-latest, nightly) (push) Waiting to run
ci / test-only-bundle (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-core (macos, macos-latest, nightly) (push) Waiting to run
ci / cross (aarch64-linux-android) (push) Waiting to run
ci / cross (aarch64-unknown-linux-gnu) (push) Waiting to run
ci / cross (i686-unknown-linux-gnu) (push) Waiting to run
ci / cross (powerpc-unknown-linux-gnu) (push) Waiting to run
ci / cross (powerpc64-unknown-linux-gnu) (push) Waiting to run
ci / cross (s390x-unknown-linux-gnu) (push) Waiting to run
ci / cross (x86_64-linux-android) (push) Waiting to run
ci / riscv32imc-unknown-none-elf (push) Waiting to run
ci / wasm32-wasip1 (push) Waiting to run
ci / wasm32-unknown-emscripten (push) Waiting to run
ci / wasm32-unknown-uknown (push) Waiting to run
ci / docsrs (push) Waiting to run
ci / rustfmt (push) Waiting to run
ci / generated (push) Waiting to run
Using `write!` unnecessarily when a simple `f.write_str` would do ends
up generating more LLVM lines on my Biff `cargo llvm-lines` benchmark.
This PR replaces those uses of `write!` with `Formatter::write_str`.
2025-12-22 15:12:28 -05:00
Andrew Gallant
21f69521cd shared: remove escaping and UTF-8 routines from shared module
With the error refactor, these are no longer used. Namely, while
switching to structured errors, I took that opportunity to slim down
errors so that we are not repeating parts of the input as often.
2025-12-22 14:28:18 -05:00
Andrew Gallant
a50f6797ce logging: small tweak to formatting
Some checks are pending
ci / msrv (push) Waiting to run
ci / examples (push) Waiting to run
ci / integrations (push) Waiting to run
ci / test-default (beta, ubuntu-latest, beta) (push) Waiting to run
ci / test-default (macos, macos-latest, stable) (push) Waiting to run
ci / test-default (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-default (stable, ubuntu-latest, stable) (push) Waiting to run
ci / test-all (macos, macos-latest, nightly) (push) Waiting to run
ci / test-core (macos, macos-latest, nightly) (push) Waiting to run
ci / test-core (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-various-feature-combos (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-release (push) Waiting to run
ci / cross (i686-unknown-linux-gnu) (push) Waiting to run
ci / cross (powerpc-unknown-linux-gnu) (push) Waiting to run
ci / cross (powerpc64-unknown-linux-gnu) (push) Waiting to run
ci / test-all (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-only-bundle (macos, macos-latest, nightly) (push) Waiting to run
ci / test-only-bundle (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-various-feature-combos (macos, macos-latest, nightly) (push) Waiting to run
ci / cross (aarch64-linux-android) (push) Waiting to run
ci / cross (aarch64-unknown-linux-gnu) (push) Waiting to run
ci / cross (s390x-unknown-linux-gnu) (push) Waiting to run
ci / cross (x86_64-linux-android) (push) Waiting to run
ci / riscv32imc-unknown-none-elf (push) Waiting to run
ci / wasm32-wasip1 (push) Waiting to run
ci / wasm32-unknown-emscripten (push) Waiting to run
ci / wasm32-unknown-uknown (push) Waiting to run
ci / docsrs (push) Waiting to run
ci / rustfmt (push) Waiting to run
ci / generated (push) Waiting to run
2025-12-22 10:08:33 -05:00
Andrew Gallant
0392d43064 error: add note about introspection 2025-12-22 10:08:33 -05:00
Andrew Gallant
523b55bc1a error: add Error::is_invalid_parameter predicate 2025-12-22 10:08:33 -05:00
Andrew Gallant
3cb0b6aefa error: add Error::is_crate_feature predicate
There's only a few of these, but they seem like a distinct category
from other error types. It's also nice to do this and standarize on the
specific error message.

The other reason I wanted to do this was to distinguish it from a
possible "is configuration error" category. (e.g., Trying to round a
span to the nearest year without a relative datatime.) These could also
be seen as configuration errors, but I want them to be in a separate
category I think.
2025-12-22 10:08:33 -05:00
Andrew Gallant
8e8033a29d error: add Error::is_range predicate
I'm somewhat concerned that this doesn't cover all cases, but I think
this should be a good start.
2025-12-22 10:08:33 -05:00
Andrew Gallant
259e8134ef error: implement an error chaining iterator
We previously only used this in the `core::fmt::Display` trait
implementation, so we just inlined it there. But we'll want to use it to
get the root of the chain for error predicates, so this commit does some
refactoring to provide a standalone internal iterator for the error
chain.
2025-12-22 10:08:33 -05:00
Andrew Gallant
831d3efb4d shared: move itime range error into itime module
Some checks failed
ci / test-miri (push) Has been cancelled
ci / test-various-feature-combos (macos, macos-latest, nightly) (push) Has been cancelled
ci / test-various-feature-combos (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-release (push) Has been cancelled
ci / test-doc (push) Has been cancelled
ci / test-bench (push) Has been cancelled
ci / test-fuzz (push) Has been cancelled
ci / win-msvc (push) Has been cancelled
ci / win-gnu (push) Has been cancelled
ci / msrv (push) Has been cancelled
ci / examples (push) Has been cancelled
ci / integrations (push) Has been cancelled
ci / time-zone-init (macos-latest) (push) Has been cancelled
ci / time-zone-init (ubuntu-24.04-arm) (push) Has been cancelled
ci / time-zone-init (ubuntu-latest) (push) Has been cancelled
ci / time-zone-init (windows-latest) (push) Has been cancelled
ci / cross (aarch64-linux-android) (push) Has been cancelled
ci / cross (aarch64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (i686-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (s390x-unknown-linux-gnu) (push) Has been cancelled
ci / cross (x86_64-linux-android) (push) Has been cancelled
ci / riscv32imc-unknown-none-elf (push) Has been cancelled
ci / wasm32-wasip1 (push) Has been cancelled
ci / wasm32-unknown-emscripten (push) Has been cancelled
ci / wasm32-unknown-uknown (push) Has been cancelled
ci / docsrs (push) Has been cancelled
ci / rustfmt (push) Has been cancelled
ci / generated (push) Has been cancelled
This follows the pattern I used for TZif and POSIX time zone parsing.
2025-12-20 14:38:20 -05:00
Andrew Gallant
26202e5d4d shared: switch POSIX time zone parsing over to structured errors 2025-12-20 14:38:20 -05:00
Andrew Gallant
ac0054c72f shared: replace some uses of write!
I believe this reduces code size.
2025-12-20 14:38:20 -05:00
Andrew Gallant
f275164239 shared: remove alloc cfgs
I guess parsing a POSIX time zone doesn't actually require `alloc` any
more. That's cool.
2025-12-20 14:38:20 -05:00
Andrew Gallant
d024322b27 shared: use structured errors for TZif parsing
For this one, I defined the error type inline with it. This just felt
right and it does stay reasonably encapsulated.

I'll probably swing back and do the same for the time range error type?
2025-12-20 14:38:20 -05:00
Andrew Gallant
973876a9f1 shared: use structured errors for shared/itime 2025-12-20 14:38:20 -05:00
Andrew Gallant
3a832162be
fmt: some minor perf improvements to strptime
Some checks are pending
ci / test-various-feature-combos (macos, macos-latest, nightly) (push) Waiting to run
ci / test-various-feature-combos (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-release (push) Waiting to run
ci / test-doc (push) Waiting to run
ci / test-bench (push) Waiting to run
ci / test-fuzz (push) Waiting to run
ci / test-miri (push) Waiting to run
ci / win-msvc (push) Waiting to run
ci / win-gnu (push) Waiting to run
ci / msrv (push) Waiting to run
ci / examples (push) Waiting to run
ci / integrations (push) Waiting to run
ci / time-zone-init (macos-latest) (push) Waiting to run
ci / time-zone-init (ubuntu-24.04-arm) (push) Waiting to run
ci / time-zone-init (ubuntu-latest) (push) Waiting to run
ci / time-zone-init (windows-latest) (push) Waiting to run
ci / cross (aarch64-linux-android) (push) Waiting to run
ci / cross (aarch64-unknown-linux-gnu) (push) Waiting to run
ci / cross (i686-unknown-linux-gnu) (push) Waiting to run
ci / cross (powerpc-unknown-linux-gnu) (push) Waiting to run
ci / cross (powerpc64-unknown-linux-gnu) (push) Waiting to run
ci / cross (s390x-unknown-linux-gnu) (push) Waiting to run
ci / cross (x86_64-linux-android) (push) Waiting to run
ci / wasm32-unknown-emscripten (push) Waiting to run
ci / wasm32-unknown-uknown (push) Waiting to run
ci / riscv32imc-unknown-none-elf (push) Waiting to run
ci / wasm32-wasip1 (push) Waiting to run
ci / docsrs (push) Waiting to run
ci / rustfmt (push) Waiting to run
ci / generated (push) Waiting to run
This adds a little inlining back to help reclaim a small performance
regression in `strptime`. This improves the relevant benchmark from
70ns to 64ns on my machine.
2025-12-19 13:11:17 -05:00
Andrew Gallant
b8757deba8 error: switch everything over to structured errors
Some checks failed
ci / test-various-feature-combos (macos, macos-latest, nightly) (push) Has been cancelled
ci / test-various-feature-combos (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-release (push) Has been cancelled
ci / test-doc (push) Has been cancelled
ci / test-bench (push) Has been cancelled
ci / test-fuzz (push) Has been cancelled
ci / test-miri (push) Has been cancelled
ci / win-msvc (push) Has been cancelled
ci / win-gnu (push) Has been cancelled
ci / msrv (push) Has been cancelled
ci / examples (push) Has been cancelled
ci / integrations (push) Has been cancelled
ci / time-zone-init (macos-latest) (push) Has been cancelled
ci / time-zone-init (ubuntu-24.04-arm) (push) Has been cancelled
ci / time-zone-init (ubuntu-latest) (push) Has been cancelled
ci / time-zone-init (windows-latest) (push) Has been cancelled
ci / cross (aarch64-linux-android) (push) Has been cancelled
ci / cross (aarch64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (i686-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (s390x-unknown-linux-gnu) (push) Has been cancelled
ci / cross (x86_64-linux-android) (push) Has been cancelled
ci / riscv32imc-unknown-none-elf (push) Has been cancelled
ci / wasm32-wasip1 (push) Has been cancelled
ci / wasm32-unknown-emscripten (push) Has been cancelled
ci / wasm32-unknown-uknown (push) Has been cancelled
ci / docsrs (push) Has been cancelled
ci / rustfmt (push) Has been cancelled
ci / generated (push) Has been cancelled
This was an incredibly tedious and tortuous refactor. But this removes
almost all of the "create ad hoc stringly-typed errors everywhere."

This partially makes progress toward #418, but my initial impetus for
doing this was to see if I could reduce binary size and improve
compilation times. My general target was to see if I could reduce total
LLVM lines. I tested this with [Biff] using this command in the root of
the Biff repo:

```
cargo llvm-lines --profile release-lto
```

Before this change, Biff had 768,596 LLVM lines. With this change, it
has 757,331 lines. So... an improvement, but a very modest one.

What about compilation times? This does seem to translate to---also a
modest---improvement. For compiling release builds of Biff. Before:

```
$ hyperfine -w1 --prepare 'cargo clean' 'cargo b -r'
Benchmark 1: cargo b -r
  Time (mean ± σ):      7.776 s ±  0.052 s    [User: 65.876 s, System: 2.621 s]
  Range (min … max):    7.690 s …  7.862 s    10 runs
```

After:

```
$ hyperfine -w1 --prepare 'cargo clean' 'cargo b -r'
Benchmark 1: cargo b -r
  Time (mean ± σ):      7.591 s ±  0.067 s    [User: 65.686 s, System: 2.564 s]
  Range (min … max):    7.504 s …  7.689 s    10 runs
```

What about dev builds? Before:

```
$ hyperfine -w1 --prepare 'cargo clean' 'cargo b'
Benchmark 1: cargo b
  Time (mean ± σ):      4.074 s ±  0.022 s    [User: 14.493 s, System: 1.818 s]
  Range (min … max):    4.037 s …  4.099 s    10 runs
```

After:

```
$ hyperfine -w1 --prepare 'cargo clean' 'cargo b'
Benchmark 1: cargo b
  Time (mean ± σ):      4.541 s ±  0.027 s    [User: 15.385 s, System: 2.081 s]
  Range (min … max):    4.503 s …  4.591 s    10 runs
```

Well... that's disappointing. A modest improvement to release builds,
but a fairly large regression in dev builds. Maybe it's because of the
additional hand-written impls for new structured error types? Bah.

And binary size? Normal release builds (not LTO) of Biff that were
stripped were 4,431,456 bytes before this change and 4,392,064 after.

Hopefully this will unlock other improvements to justify doing this.
Note also that this slims down a number of error messages.

[Biff]: https://github.com/BurntSushi/biff
2025-12-16 16:51:01 -05:00
Andrew Gallant
3765a52b8d fmt: add &mut dyn Write impl for jiff::fmt::Write
I was playing with using this to avoid parametric polymorphism
costs, but I couldn't find my way to a concrete benefit.
Either way, this impl should exist for people that want to
use it.
2025-12-16 16:51:01 -05:00
Andrew Gallant
42080c4e71 fmt/strtime: avoid inlining the or_else cases
These all generally call `BrokenDownTime::to_date`, which
adds a fair bit of code. Since these are the uncommon case,
let's not inline that goop.
2025-12-16 16:51:01 -05:00
Andrew Gallant
40941a5188 fmt/strtime: tighten up to_timestamp and to_date
Both of these functions are marked as `inline`, but they can
be quite beefy. Instead, set the inlineable implementation
as the common case, and put the rest behind a non-inlineable
function.
2025-12-16 16:51:01 -05:00
Andrew Gallant
3780351543 rangeint: don't try to inline error constructor 2025-12-16 16:51:01 -05:00
Andrew Gallant
54c1b2d25b error: make map_err closures as cold and non-inlineable
This doesn't seem to have much impact as shown via a
`cargo llvm-lines`. But this still seems like good sense
to have.
2025-12-16 16:51:01 -05:00
Andrew Gallant
aa361bbfc2 fmt: un-generic a function
This reduces code size somewhat.

There are probably more things like this, but I picked
this one to test its effects. It got rid of a few LLVM
lines from an LTO-compiled binary that uses Jiff. But
not much.
2025-12-16 16:51:01 -05:00
Andrew Gallant
34359896a4
fuzz: update dependencies
Some checks failed
ci / test-various-feature-combos (macos, macos-latest, nightly) (push) Has been cancelled
ci / test-various-feature-combos (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-release (push) Has been cancelled
ci / test-doc (push) Has been cancelled
ci / test-bench (push) Has been cancelled
ci / test-fuzz (push) Has been cancelled
ci / test-miri (push) Has been cancelled
ci / win-msvc (push) Has been cancelled
ci / win-gnu (push) Has been cancelled
ci / msrv (push) Has been cancelled
ci / examples (push) Has been cancelled
ci / integrations (push) Has been cancelled
ci / time-zone-init (macos-latest) (push) Has been cancelled
ci / time-zone-init (ubuntu-24.04-arm) (push) Has been cancelled
ci / time-zone-init (ubuntu-latest) (push) Has been cancelled
ci / time-zone-init (windows-latest) (push) Has been cancelled
ci / cross (aarch64-linux-android) (push) Has been cancelled
ci / cross (aarch64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (i686-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (s390x-unknown-linux-gnu) (push) Has been cancelled
ci / cross (x86_64-linux-android) (push) Has been cancelled
ci / riscv32imc-unknown-none-elf (push) Has been cancelled
ci / wasm32-wasip1 (push) Has been cancelled
ci / wasm32-unknown-emscripten (push) Has been cancelled
ci / wasm32-unknown-uknown (push) Has been cancelled
ci / docsrs (push) Has been cancelled
ci / rustfmt (push) Has been cancelled
ci / generated (push) Has been cancelled
2025-12-12 17:35:45 -05:00
Andrew Gallant
f889e5b40a
jiff-tzdb-0.1.5
Some checks failed
ci / test-doc (push) Has been cancelled
ci / test-bench (push) Has been cancelled
ci / test-various-feature-combos (macos, macos-latest, nightly) (push) Has been cancelled
ci / test-various-feature-combos (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-release (push) Has been cancelled
ci / test-fuzz (push) Has been cancelled
ci / test-miri (push) Has been cancelled
ci / win-msvc (push) Has been cancelled
ci / win-gnu (push) Has been cancelled
ci / msrv (push) Has been cancelled
ci / examples (push) Has been cancelled
ci / integrations (push) Has been cancelled
ci / time-zone-init (macos-latest) (push) Has been cancelled
ci / time-zone-init (ubuntu-24.04-arm) (push) Has been cancelled
ci / time-zone-init (ubuntu-latest) (push) Has been cancelled
ci / time-zone-init (windows-latest) (push) Has been cancelled
ci / cross (aarch64-linux-android) (push) Has been cancelled
ci / cross (aarch64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (i686-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (s390x-unknown-linux-gnu) (push) Has been cancelled
ci / cross (x86_64-linux-android) (push) Has been cancelled
ci / riscv32imc-unknown-none-elf (push) Has been cancelled
ci / wasm32-wasip1 (push) Has been cancelled
ci / wasm32-unknown-emscripten (push) Has been cancelled
ci / wasm32-unknown-uknown (push) Has been cancelled
ci / docsrs (push) Has been cancelled
ci / rustfmt (push) Has been cancelled
ci / generated (push) Has been cancelled
2025-12-10 20:44:39 -05:00
Andrew Gallant
4526cd2663 jiff-tzdb: update to tzdb 2025c
Ref: https://lists.iana.org/hyperkitty/list/tz-announce@iana.org/thread/TAGXKYLMAQRZRFTERQ33CEKOW7KRJVAK/
2025-12-10 20:44:22 -05:00
Addison Crump
9d7e099a7a fuzz: add initial set of fuzzer targets
Some checks failed
ci / test-various-feature-combos (macos, macos-latest, nightly) (push) Has been cancelled
ci / test-various-feature-combos (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-release (push) Has been cancelled
ci / test-doc (push) Has been cancelled
ci / test-bench (push) Has been cancelled
ci / test-fuzz (push) Has been cancelled
ci / test-miri (push) Has been cancelled
ci / win-msvc (push) Has been cancelled
ci / win-gnu (push) Has been cancelled
ci / msrv (push) Has been cancelled
ci / examples (push) Has been cancelled
ci / integrations (push) Has been cancelled
ci / time-zone-init (macos-latest) (push) Has been cancelled
ci / time-zone-init (ubuntu-24.04-arm) (push) Has been cancelled
ci / time-zone-init (ubuntu-latest) (push) Has been cancelled
ci / time-zone-init (windows-latest) (push) Has been cancelled
ci / cross (aarch64-linux-android) (push) Has been cancelled
ci / cross (aarch64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (s390x-unknown-linux-gnu) (push) Has been cancelled
ci / cross (i686-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (x86_64-linux-android) (push) Has been cancelled
ci / riscv32imc-unknown-none-elf (push) Has been cancelled
ci / wasm32-wasip1 (push) Has been cancelled
ci / wasm32-unknown-emscripten (push) Has been cancelled
ci / wasm32-unknown-uknown (push) Has been cancelled
ci / docsrs (push) Has been cancelled
ci / rustfmt (push) Has been cancelled
ci / generated (push) Has been cancelled
There's a lot more that we could do, but this should be a good start.
2025-11-08 10:33:22 -05:00
Azan Ali
552b9d1fef civil: added FromStr and Display impls for ISOWeekDate
Some checks are pending
ci / test-various-feature-combos (macos, macos-latest, nightly) (push) Waiting to run
ci / test-various-feature-combos (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-release (push) Waiting to run
ci / test-doc (push) Waiting to run
ci / test-bench (push) Waiting to run
ci / test-miri (push) Waiting to run
ci / win-msvc (push) Waiting to run
ci / win-gnu (push) Waiting to run
ci / msrv (push) Waiting to run
ci / examples (push) Waiting to run
ci / integrations (push) Waiting to run
ci / time-zone-init (macos-latest) (push) Waiting to run
ci / time-zone-init (ubuntu-24.04-arm) (push) Waiting to run
ci / time-zone-init (ubuntu-latest) (push) Waiting to run
ci / time-zone-init (windows-latest) (push) Waiting to run
ci / test-default (beta, ubuntu-latest, beta) (push) Waiting to run
ci / cross (aarch64-linux-android) (push) Waiting to run
ci / cross (aarch64-unknown-linux-gnu) (push) Waiting to run
ci / cross (i686-unknown-linux-gnu) (push) Waiting to run
ci / cross (powerpc-unknown-linux-gnu) (push) Waiting to run
ci / cross (powerpc64-unknown-linux-gnu) (push) Waiting to run
ci / cross (s390x-unknown-linux-gnu) (push) Waiting to run
ci / cross (x86_64-linux-android) (push) Waiting to run
ci / riscv32imc-unknown-none-elf (push) Waiting to run
ci / wasm32-wasip1 (push) Waiting to run
ci / wasm32-unknown-emscripten (push) Waiting to run
ci / wasm32-unknown-uknown (push) Waiting to run
ci / docsrs (push) Waiting to run
ci / rustfmt (push) Waiting to run
ci / generated (push) Waiting to run
This also includes `Deserialize` and `Serialize` Serde impls, deferring
to `FromStr` and `Display`, respectively.

This brings `ISOWeekDate` into parity with the other datetime types in
terms of parsing/printing.

N.B. In this commit, we start trying to make error messages a little
more consistent. So there are some changes here that impact the messages
other than ISO 8601 week date parsing.

Closes #412
2025-11-07 21:38:38 -05:00
Andrew Gallant
6bab68dc24
jiff-icu-0.2.2
Some checks are pending
ci / time-zone-init (windows-latest) (push) Waiting to run
ci / test-default (beta, ubuntu-latest, beta) (push) Waiting to run
ci / test-default (macos, macos-latest, stable) (push) Waiting to run
ci / test-default (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-default (stable, ubuntu-latest, stable) (push) Waiting to run
ci / test-all (macos, macos-latest, nightly) (push) Waiting to run
ci / test-all (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-only-bundle (macos, macos-latest, nightly) (push) Waiting to run
ci / test-only-bundle (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-core (macos, macos-latest, nightly) (push) Waiting to run
ci / test-core (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-various-feature-combos (macos, macos-latest, nightly) (push) Waiting to run
ci / test-various-feature-combos (nightly, ubuntu-latest, nightly) (push) Waiting to run
ci / test-release (push) Waiting to run
ci / test-doc (push) Waiting to run
ci / test-bench (push) Waiting to run
ci / cross (aarch64-linux-android) (push) Waiting to run
ci / cross (aarch64-unknown-linux-gnu) (push) Waiting to run
ci / cross (i686-unknown-linux-gnu) (push) Waiting to run
ci / cross (powerpc-unknown-linux-gnu) (push) Waiting to run
ci / cross (powerpc64-unknown-linux-gnu) (push) Waiting to run
ci / cross (s390x-unknown-linux-gnu) (push) Waiting to run
ci / cross (x86_64-linux-android) (push) Waiting to run
ci / riscv32imc-unknown-none-elf (push) Waiting to run
ci / wasm32-wasip1 (push) Waiting to run
ci / wasm32-unknown-emscripten (push) Waiting to run
ci / wasm32-unknown-uknown (push) Waiting to run
ci / docsrs (push) Waiting to run
ci / rustfmt (push) Waiting to run
ci / generated (push) Waiting to run
2025-11-07 08:22:47 -05:00
Andrew Gallant
422353bb0c jiff-icu: add TryFrom impls for icu_time::zone::models::AtTime
It looks like `icu_time::zone::models::Full` has been deprecated. So we
need some `allow(deprecated)` to squash the warnings. And we implement a
`TryFrom` for `ZonedDateTime<Iso, TimeZoneInfo<AtTime>>` as its
replacement.

Previously, I think this would have lost some information, but it sounds
like icu4x can now figure out the right DST status without being told.

Ref https://github.com/unicode-org/icu4x/pull/6754
Ref https://github.com/unicode-org/icu4x/pull/6755
2025-11-07 08:22:32 -05:00
Andrew Gallant
0a91070f27
changelog: 0.2.16
I did this after the fact. I'll hold off doing another release just for
this, since this just includes a summary and a date. The actual items
don't change.
2025-11-07 07:58:08 -05:00
Andrew Gallant
ba1de61e1b
jiff-icu-0.2.1 2025-11-07 07:54:58 -05:00
Andrew Gallant
2ef6045d57
0.2.16 2025-11-07 07:53:58 -05:00
Andrew Gallant
0b293b416d
doc: a few documentation fixes 2025-11-07 07:50:44 -05:00
Andrew Gallant
0fe02f2d49 changelog: add entries for duration work 2025-11-07 07:40:15 -05:00
Abdulrazaq Alhendi
b9484eaa48 fmt/serde: add helpers for std::time::Duration
This commit writes out the Serde helpers for unsigned durations.

This is the pay off for adding the dedicated parsers/printers for a
`std::time::Duration`. Previously, we were converting to/from a
`SignedDuration`, which fundamentally limited the range of values we
could support.

Closes #380, Ref #298
2025-11-07 07:40:15 -05:00
Andrew Gallant
87c607bb72 fmt: add parsing routines for std::time::Duration
This was a little hairier than printing, but still overall pretty easy
given my previous changes!
2025-11-07 07:40:15 -05:00
Andrew Gallant
8a7f2492fd fmt: add support for printing std::time::Duration
This was thankfully as straight-forward as I was hoping!
2025-11-07 07:40:15 -05:00
Andrew Gallant
3e49cbed78 signed_duration: remove extraneous comments 2025-11-07 07:40:15 -05:00
Andrew Gallant
b5f30f2324 fmt: make fractional formatting use u32
I think when I originally wrote fractional formatting, I was thinking
about using precision values greater than `9`. But that never really
panned out. And I used signed values because I used signed values
everywhere.

I think this is the last change we need to be able to feasibly add
native `std::time::Duration` support.
2025-11-07 07:40:15 -05:00
Andrew Gallant
8e61ffd5e2 fmt: add unsigned integer formatting
... so that we can print `u64` values as-is without suspicious casts.
Unsigned integer printing is also simpler, so it's plausible that it's
faster too. Although I haven't been careful about benchmarking duration
printing.

In the next commit, we will finish removing the casts by tweaking
fractional printing.
2025-11-07 07:40:15 -05:00
Andrew Gallant
191006379b fmt: refactor friendly printer to use std::time::Duration
This is continued progress toward natively supporting
`std::time::Duration`. I basically didn't want to duplicate all of the
code used to print a `SignedDuration` just so that we could print a
`std::time::Duration`. Since we handle the sign before/after most of the
meat of printing, we can actually lower a `SignedDuration` to a
`std::time::Duration` and focus most of our printing logic from that.

There are some papercuts in this commit though. Notably, some casts
between `u64` and `i64`, since Jiff's lowest level integer printing
routine requires a `u64`. We'll fix that in the next commit.

Thank goodness I decided to make `SignedDuration` mimic
`std::time::Duration` exactly (except for being signed). That made this
change super easy.
2025-11-07 07:40:15 -05:00
Andrew Gallant
9b46e2e0c1 fmt: optimize parsing into Span
We do something similar like we did for `SignedDuration`: we carve out a
fast path that generally lets us quickly skip error checking and what
not. Overall comparison with current `master`
(211a36d5ec):

    group                                             master                                 new
    -----                                             ------                                 ---
    parse/friendly/long/span/jiff                     3.26    104.3±0.48ns        ? ?/sec    1.00     32.0±0.34ns        ? ?/sec
    parse/friendly/longer/span/jiff                   3.18    105.7±0.35ns        ? ?/sec    1.00     33.2±0.20ns        ? ?/sec
    parse/friendly/longest-time/duration/jiff         1.26     41.9±0.69ns        ? ?/sec    1.00     33.3±0.62ns        ? ?/sec
    parse/friendly/longest-time/span/jiff             3.31    122.1±0.32ns        ? ?/sec    1.00     36.8±0.28ns        ? ?/sec
    parse/friendly/longest/span/jiff                  3.22    160.5±0.48ns        ? ?/sec    1.00     49.8±0.47ns        ? ?/sec
    parse/friendly/medium/span/jiff                   2.93     62.3±0.13ns        ? ?/sec    1.00     21.2±0.16ns        ? ?/sec
    parse/friendly/short/duration/jiff                1.20     15.7±0.27ns        ? ?/sec    1.00     13.0±0.25ns        ? ?/sec
    parse/friendly/short/span/jiff                    2.69     49.8±0.19ns        ? ?/sec    1.00     18.5±0.04ns        ? ?/sec
    parse/friendly/tiny/duration/jiff                 1.08      8.1±0.36ns        ? ?/sec    1.00      7.5±0.13ns        ? ?/sec
    parse/friendly/tiny/span/jiff                     2.09     34.1±0.11ns        ? ?/sec    1.00     16.3±0.08ns        ? ?/sec
    parse/iso8601_duration/long-time/duration/jiff    1.12     27.6±0.32ns        ? ?/sec    1.00     24.7±0.22ns        ? ?/sec
    parse/iso8601_duration/long-time/span/jiff        1.28     76.6±0.17ns        ? ?/sec    1.00     59.7±0.23ns        ? ?/sec
    parse/iso8601_duration/long/span/jiff             4.36    101.8±0.21ns        ? ?/sec    1.00     23.4±0.14ns        ? ?/sec
    parse/iso8601_duration/medium/span/jiff           3.18     60.3±0.12ns        ? ?/sec    1.00     19.0±0.11ns        ? ?/sec
    parse/iso8601_duration/short/duration/jiff        1.49     12.1±0.22ns        ? ?/sec    1.00      8.1±0.14ns        ? ?/sec
    parse/iso8601_duration/short/span/jiff            2.68     47.7±0.12ns        ? ?/sec    1.00     17.8±0.22ns        ? ?/sec
    parse/iso8601_duration/tiny/duration/jiff         1.10      6.7±0.10ns        ? ?/sec    1.00      6.0±0.06ns        ? ?/sec
    parse/iso8601_duration/tiny/span/jiff             2.00     33.1±0.08ns        ? ?/sec    1.00     16.5±0.08ns        ? ?/sec

Very happy with this. Especially getting some of the 100ns+ benchmarks
down to something much more reasonable is amazing.
2025-11-07 07:40:15 -05:00
Andrew Gallant
1cb039f707 fmt: fix i64::MIN bug in ISO 8601 duration parsing
This only applies to parsing into a `SignedDuration` since `i64::MIN`
isn't supported by any units on `Span` (including nanoseconds, since it
only supports `(i64::MIN+1)..=i64::MAX` to make negations infallible).

We pull out the u64 prefix parser from the friendly duration and use
that. Since that does the parsing in a single pass and is overall
generally tighter, this also leads to a nice perf improvement on ISO
8601 duration parsing:

    group                                             master                                 new
    -----                                             ------                                 ---
    parse/iso8601_duration/long-time/duration/jiff    1.14     27.6±0.32ns        ? ?/sec    1.00     24.2±0.24ns        ? ?/sec
    parse/iso8601_duration/long-time/span/jiff        1.21     76.6±0.17ns        ? ?/sec    1.00     63.2±0.24ns        ? ?/sec
    parse/iso8601_duration/long/span/jiff             2.14    101.8±0.21ns        ? ?/sec    1.00     47.4±0.24ns        ? ?/sec
    parse/iso8601_duration/medium/span/jiff           1.71     60.3±0.12ns        ? ?/sec    1.00     35.2±0.12ns        ? ?/sec
    parse/iso8601_duration/short/duration/jiff        1.56     12.1±0.22ns        ? ?/sec    1.00      7.8±0.13ns        ? ?/sec
    parse/iso8601_duration/short/span/jiff            1.50     47.7±0.12ns        ? ?/sec    1.00     31.9±0.08ns        ? ?/sec
    parse/iso8601_duration/tiny/duration/jiff         1.17      6.7±0.10ns        ? ?/sec    1.00      5.7±0.03ns        ? ?/sec
    parse/iso8601_duration/tiny/span/jiff             1.19     33.1±0.08ns        ? ?/sec    1.00     27.8±0.10ns        ? ?/sec

The results above are compared against current `master`
(`211a36d5ecddf1aeb9b00648d9d5e631a5420903`).
2025-11-07 07:40:15 -05:00
Andrew Gallant
206f08100d fmt: more clean up
This DRY's up some code and tightens up a few things.
2025-11-07 07:40:15 -05:00
Andrew Gallant
8f75807b5e fmt: optimize parsing SignedDuration
The "before" here reflects `master`
(`211a36d5ec`) and not the previous
commit:

    group                                             master                                 new
    -----                                             ------                                 ---
    parse/friendly/longest-time/duration/jiff         1.29     41.9±0.69ns        ? ?/sec    1.00     32.4±0.42ns        ? ?/sec
    parse/friendly/short/duration/jiff                1.14     15.7±0.27ns        ? ?/sec    1.00     13.8±0.30ns        ? ?/sec
    parse/friendly/tiny/duration/jiff                 1.23      8.1±0.36ns        ? ?/sec    1.00      6.6±0.11ns        ? ?/sec
    parse/iso8601_duration/long-time/duration/jiff    1.00     27.6±0.32ns        ? ?/sec    1.06     29.3±0.27ns        ? ?/sec
    parse/iso8601_duration/short/duration/jiff        1.05     12.1±0.22ns        ? ?/sec    1.00     11.5±0.20ns        ? ?/sec
    parse/iso8601_duration/tiny/duration/jiff         1.00      6.7±0.10ns        ? ?/sec    1.15      7.7±0.09ns        ? ?/sec

There are some minor regressions, but also some wins, particularly for
the friendly format.

I mostly focused on optimizing the "turn parsed values into a
`SignedDuration`" part. I used a data dependent optimization that
quickly detects whether we can avoid error handling entirely.

We could probably optimize the general case a bit more too. But this is
enough for now.
2025-11-07 07:40:15 -05:00
Andrew Gallant
ce51de3982 fmt: massively refactor duration parsing
This introduces a new internal helper type, `DurationUnits`, that is
used to parse all duration types and formats. It centralizes the logic
and trims away a lot of fat. This should reduce code size (although I
haven't checked) and also improve perf. Currently, it does significantly
improve perf for parsing longer durations and especially for `Span`. It
does however slightly regress perf for parsing shorter `SignedDuration`
values.

However, I think there are a lot of perf improvement opportunities. I'll
put those in a subsequent commit.

(We still haven't implemented `std::time::Duration` yet. But
`DurationUnits` is clearly designed with it in mind. This is one helluva
yak shave!)

This also fixes a long-standing bug where we couldn't parse
`abs(i64::MIN) secs ago`. The `DurationUnits` design was specifically
motivated (in part) by this.
2025-11-07 07:40:15 -05:00
Andrew Gallant
da7a745635 zoned: fix copy & paste transcription error 2025-11-07 07:40:15 -05:00