mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
* Use chrono for UTC/calendar conversion instead of hand-rolled copies Replaces the hand-rolled Howard Hinnant civil/days-from-civil copies and the leap-year/days-in-month tables with chrono as a workspace dependency: - apps/vectorcraft/src/logging.rs: timestamp (log line time) - crates/doc/src/metadata.rs: civil (Unix seconds -> [y,m,d,h,mi,s]) and iso8601 - crates/pdf/src/file_info.rs: unix (date -> seconds) and in_month, used by the PDF/XMP date parsers (pdf_date, xmp_date) Output formats and parsing semantics are unchanged and pinned by the existing tests (PDF D:... and XMP dates, offsets, leap-year rejection, year clamp 0-9999, pre-epoch clamp). chrono uses only std, so wasm stays safe. AGENTS.md/CLAUDE.md now say time goes through chrono. Follow-up to storytold/cadcraft#1785 * Never panic on a clock outside chrono's range; keep 5-digit years unprefixed chrono's From<SystemTime> unwraps, so a clock past year 262143 panicked inside the logger. timestamp now uses the fallible DateTime::from_timestamp and reads such a clock (or a pre-epoch one) as the epoch instead. Years past 9999 are written with {:04} like before, because %Y would add a '+'. Tests cover the out-of-range and 5-digit-year cases. * Don't build an unrepresentable SystemTime in the far-future test UNIX_EPOCH + Duration::from_secs(u64::MAX / 2) overflows Windows' SystemTime and panicked before timestamp() ran, failing the Windows test job. Build it with checked_add and only assert where it exists. * time: preserve old out-of-range date conversion (no epoch fallback) `DateTime::from_timestamp(...).unwrap_or_default()` silently reset any instant past chrono's year range to 1970-01-01. Restore the old conversion domain with a cycle-based helper that routes the calendar through chrono (the calendar repeats every 400 years = 146_097 days, so month/day/time come from chrono and only the year is carried in i128, keeping every i64 exact). - apps/vectorcraft/src/logging.rs: `timestamp` via `utc_parts`; keep the pre-1970 epoch clamp; u64 secs past i64::MAX saturate, not epoch. - crates/doc/src/metadata.rs: `civil` cycle-based, keeping its clamp EXACTLY as the old code had it: the input is clamped to 0000-01-01..9999-12-31 first and the year is clamped to 0..=9999 afterwards. (With the input clamp the old `unwrap_or_default()` was already unreachable; this drops it and makes the conversion explicit, with identical output.) Pinned old outputs in tests: logging u64::MAX/2 s -> 292277026596-12-04T15:30:07.000Z (was epoch), 10_000_000_000_000 s -> 318857-05-20T17:46:40.000Z metadata civil(i64::MIN)[0]=0, civil(i64::MAX)[0]=9999; iso8601(i64::MIN)=0000-01-01T00:00:00Z, iso8601(i64::MAX)=9999-12-31T23:59:59Z (year clamp, as before) * Don't build a year-318857 SystemTime unchecked in the logging test Windows' SystemTime only reaches about year 30828, so UNIX_EPOCH + Duration::from_secs(10_000_000_000_000) panicked before timestamp() ran and failed the Windows test job. Build it with checked_add and assert where the platform can hold it. The year-10000 case fits everywhere and stays unconditional. * Name the 400-year range extension as the one exception to the time rule The rule said never to hand-roll calendar math, but the range fix (shifting by whole 400-year Gregorian cycles so dates past chrono's year range keep their old output) is cycle arithmetic, so the rule and the code disagreed. The rule now names that exception: the library still computes month, day and time, and only whole cycles are carried in the year. * Say the library computes month and day; time-of-day is plain arithmetic Narrows the range-extension wording: the date library computes the calendar fields, and splitting seconds into hours, minutes and seconds is ordinary arithmetic, which is what the code does.
28 lines
771 B
TOML
28 lines
771 B
TOML
[package]
|
|
name = "vectorcraft-doc"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
description = "VectorCraft document model: artboards, layers, objects, appearance (pure data + serde)"
|
|
|
|
[lints]
|
|
workspace = true
|
|
|
|
[dependencies]
|
|
vectorcraft-geom = { workspace = true }
|
|
vectorcraft-color = { workspace = true }
|
|
kurbo = { workspace = true }
|
|
image = { workspace = true }
|
|
tiff = { workspace = true }
|
|
# 1-bit TIFFs compressed with CCITT Group 3 (Compression 2 and 3).
|
|
hayro-ccitt = { workspace = true }
|
|
zune-jpeg = { workspace = true }
|
|
serde = { workspace = true }
|
|
serde_json = { workspace = true }
|
|
thiserror = { workspace = true }
|
|
chrono = { workspace = true }
|
|
|
|
[dev-dependencies]
|
|
jpeg-encoder = { workspace = true }
|
|
proptest = { workspace = true }
|