Fix parser fallback and improve wareki performance - #29
Conversation
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
There was a problem hiding this comment.
Code Review
This pull request introduces performance optimizations and robustness improvements to the wareki library. It adds an early-return fast path for ASCII-only date strings, caches simple Kansuji conversions for numbers 0–99, deep-freezes calendar year definitions to prevent modification, and ensures that UnsupportedDateRange errors are preserved rather than falling back to standard parsing. The review feedback suggests adding an explicit type check in the new to_simple_kan helper to prevent runtime errors when non-integer values are passed.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Pull request overview
This PR tightens the boundary between Wareki parsing and stdlib parsing (preserving Wareki::UnsupportedDateRange for recognized-but-unsupported inputs), while also reducing overhead on hot parsing/formatting paths via an ASCII fast-path and a small kansuji cache. It additionally makes the lunisolar calendar definition data immutable (deep-freeze) and updates the generator to keep that invariant.
Changes:
- Preserve
Wareki::UnsupportedDateRangeby removing it from stdlib-fallback rescue paths inWareki.parse_to_dateand theDatemonkey-patches. - Add an ASCII-only fast path for
Date.parse/Date._parseto bypass Wareki normalization/filtering when not needed. - Cache
0..99:simplekansuji strings (returning mutable copies) and deep-freezeYEAR_DEFS(and generator output) to prevent runtime mutation.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| spec/wareki_spec.rb | Updates expectations to require UnsupportedDateRange preservation for recognized Wareki inputs. |
| spec/utils_spec.rb | Adds coverage for kansuji cache behavior/mutability and deep-freeze invariants on calendar definitions. |
| spec/std_ext_spec.rb | Adds regression tests for unsupported-range errors, ASCII fast path, and non-ASCII Wareki path behavior. |
| lib/wareki/utils.rb | Introduces SIMPLE_KANSUJI_CACHE and to_simple_kan, and switches time formatting to use the cache. |
| lib/wareki/std_ext.rb | Adds ASCII-only direct delegation to original parsers; preserves unsupported-range errors by narrowing rescue. |
| lib/wareki/date.rb | Switches date-format kansuji directives to use Utils.to_simple_kan. |
| lib/wareki/common.rb | Preserves unsupported-range errors in parse_to_date by narrowing rescue to ArgumentError. |
| lib/wareki/calendar_def.rb | Implements deep-freeze of year definitions and nested arrays, then freezes YEAR_DEFS. |
| build-util/gen-jp-cal-def.rb | Updates generator to emit the same deep-freeze structure as calendar_def.rb. |
| docs/superpowers/plans/2026-07-14-parse-fast-path-and-calendar-freeze.md | Documents the ASCII fast-path + deep-freeze work plan. |
| docs/superpowers/plans/2026-07-14-fallback-and-kansuji-performance-fixes.md | Documents the fallback boundary + kansuji cache work plan. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Codex <codex@openai.com>
Move the era-definitions regeneration entry from the 2.0.0 section to 2.1.0; it was merged after the v2.0.0 tag, and the released 2.0.0 gem still contains the old era boundaries. Also add the post-2.0.0 parser and kansuji changes from PR #29. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0183s3PMdYWFbdUEkQQcYaUz
Summary
Wareki::UnsupportedDateRangefor recognized but unsupported wareki dates instead of falling back to stdlib parsingDate.parseandDate._parseinputs directly to the saved stdlib parsersPerformance
%JF: about 30.8 µs to 2.1 µs per call%JTF: about 32.1 µs to 2.5 µs per callDate.parse: about 2.8 µs to 2.2 µs per call, approximately 0.01 µs above the saved stdlib parser in the independent review runThe kansuji cache adds about 0.95 ms and 9,400 transient allocations during initialization, so the formatting numbers describe steady-state performance.
Deep-freezing all 1,428 calendar year definitions adds about 0.07 ms during initialization.
Correctness and compatibility
Wareki.parse_to_date,Date.parse,Date._parse, andTime.parsenow agree on unsupported wareki rangesYEAR_DEFS, everyYear, and theirmonth_startsandmonth_daysarrays are frozenTest plan
bundle exec rspec(92 examples, 0 failures)bundle exec rubocop(17 files, no offenses)Implementation plans
docs/superpowers/plans/2026-07-14-fallback-and-kansuji-performance-fixes.mddocs/superpowers/plans/2026-07-14-parse-fast-path-and-calendar-freeze.md