rebuild the engine in Rust

Python was never the house language here: the mw-* desktop surface it came
from is 39 bash scripts and was exactly one Python script, the one this was
extracted from. What it cost was distribution, a widget dependency that
needed pipx and a Python floor, and 24ms of interpreter startup before a line
of the program ran.

The port is verified rather than asserted. Both implementations were run over
199,446 day-records, 26 jurisdictions across 21 years, with every field of
every record required to match; the JSON, the iCalendar and 480 renderings of
the text output are identical too. examples/dump.rs is the harness.

What the type system actually buys, which is less than the usual claim and
more than nothing:

  - Level is an ordered enum, strictest first, so  reads as 'a is
    stricter' and relaxed_to() is the one place a feast can lift a fast. No
    rule can get the direction backwards.
  - Date is a newtype over the Julian Day Number and JulianDate is a separate
    type, so a civil date and an ecclesiastical one cannot be mixed up. That
    confusion is the single most common way calendar code goes wrong.
  - Octets is a newtype in the iCalendar folder, because the bug it replaced
    counted characters against a limit RFC 5545 states in octets.
  - Movables is a struct, not a map, so a mistyped key is a compile error
    rather than a None at the far end of the program.

Of the six defects an adversarial review found in the Python, exactly one had
a shape a type system would have caught. The rest were logic, and the tests
came with them.

The menologion is compiled in with include_str!, so the binary answers on its
own: 930KB, no runtime, 1.2ms to start against Python's 36ms.
This commit is contained in:
funkpower
2026-09-18 11:13:15 -04:00
parent 8247b51805
commit d115616eff
44 changed files with 3367 additions and 2287 deletions
+30
View File
@@ -0,0 +1,30 @@
[package]
name = "typikon"
version = "0.2.0"
edition = "2021"
rust-version = "1.74"
description = "The Orthodox liturgical day: feasts, seasons and the fast, computed rather than fetched"
license = "GPL-2.0-only"
repository = "https://git.pumpin.online/funkpower/typikon"
readme = "README.md"
keywords = ["orthodox", "liturgical", "calendar", "byzantine", "pascha"]
categories = ["command-line-utilities", "date-and-time"]
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
clap = { version = "4", features = ["derive"] }
[profile.release]
strip = true
lto = true
codegen-units = 1
panic = "abort"
[[bin]]
name = "typikon"
path = "src/main.rs"
[lib]
name = "typikon"
path = "src/lib.rs"