mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-25 02:07:09 -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.
106 lines
5.7 KiB
TOML
106 lines
5.7 KiB
TOML
[package]
|
|
name = "vectorcraft"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
publish = false
|
|
default-run = "vectorcraft"
|
|
|
|
[lints]
|
|
workspace = true
|
|
|
|
[features]
|
|
default = ["wgpu", "accessibility"]
|
|
wgpu = ["eframe/wgpu", "dep:winsafe"]
|
|
accessibility = ["eframe/accesskit"]
|
|
# Build with --no-default-features --features windows7 and the win7 Rust target.
|
|
windows7 = ["eframe/glow"]
|
|
|
|
[dependencies]
|
|
vectorcraft-engine = { workspace = true, features = ["bundled-fonts"] }
|
|
vectorcraft-ui-egui = { workspace = true }
|
|
vectorcraft-text = { workspace = true }
|
|
# Shared across the Craft suite: decides who draws the window frame per desktop (compositor vs app)
|
|
# so VectorCraft matches the rest on Linux. `egui` adds `craft_window::decorate`. See #217.
|
|
craft-window = { workspace = true }
|
|
eframe = { workspace = true, features = ["default_fonts", "wayland", "x11"] }
|
|
egui = { workspace = true }
|
|
serde_json = { workspace = true }
|
|
log = { workspace = true }
|
|
chrono = { workspace = true }
|
|
|
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
|
rfd = { workspace = true }
|
|
# wayland-data-control: native Wayland clipboard (Linux; X11 through XWayland only sees what X11 apps copied).
|
|
arboard = { workspace = true, features = ["image-data", "wayland-data-control"] }
|
|
image = { workspace = true }
|
|
webbrowser = { workspace = true }
|
|
# The window's monitors, size and position (the same winit eframe runs on).
|
|
winit = { version = "0.30", default-features = false }
|
|
|
|
# The win7 target retains the viewer fallback; craft-print's WinRT PDF renderer needs newer Windows.
|
|
[target.'cfg(all(not(target_arch = "wasm32"), not(target_vendor = "win7")))'.dependencies]
|
|
craft-print = { workspace = true }
|
|
|
|
[target.'cfg(windows)'.dependencies]
|
|
clipboard-win = { workspace = true }
|
|
# Which GPU drives which display (EnumDisplayDevices, src/gpu.rs), so the window is drawn on the
|
|
# GPU that shows it: drawing on a GPU without a monitor reset the display driver. Safe wrappers over
|
|
# Win32 (MIT); the `user` feature is User32.dll only. Only the wgpu renderer chooses an adapter.
|
|
winsafe = { version = "0.0.29", default-features = false, features = ["user"], optional = true }
|
|
|
|
# DirectWrite's system font collection (src/system_fonts.rs): fonts that font services such as
|
|
# Adobe Fonts load in place (#579). MIT OR Apache-2.0, already in the build through accesskit.
|
|
[target.'cfg(all(windows, not(target_vendor = "win7")))'.dependencies]
|
|
windows = { version = "0.62", features = ["Win32_Graphics_DirectWrite"] }
|
|
|
|
[target.'cfg(target_os = "macos")'.dependencies]
|
|
# The macOS menu bar (src/mac_menu.rs): Tauri's menu crate, AppKit menus behind a safe API (no GTK
|
|
# with default features off). Pinned exactly: review the diff before bumping.
|
|
muda = { version = "=0.21.1", default-features = false }
|
|
objc2 = "0.6"
|
|
objc2-app-kit = { version = "0.3", default-features = false, features = ["std", "block2", "objc2-core-foundation", "NSApplication", "NSButton", "NSColor", "NSColorSampler", "NSColorSpace", "NSControl", "NSMenu", "NSEvent", "NSPasteboard", "NSPopUpButton", "NSResponder", "NSSavePanel", "NSTextField", "NSTextInputContext", "NSView", "NSWindow"] }
|
|
# Files opened from Finder and the Dock (src/open_documents.rs) and pasted bitmaps (src/clipboard.rs); both already come with winit, muda and rfd.
|
|
objc2-foundation = { version = "0.3", default-features = false, features = ["std", "block2", "NSArray", "NSData", "NSGeometry", "NSNotification", "NSOperation", "NSString", "NSURL"] }
|
|
block2 = "0.6"
|
|
# The window's AppKit view, to centre its buttons on the app bar (src/mac_window.rs). MIT OR
|
|
# Apache-2.0 OR Zlib, already in the build through eframe and winit.
|
|
raw-window-handle = "0.6"
|
|
# CoreText's font manager (src/mac_fonts.rs): fonts that apps and font managers register from their
|
|
# own folders (#579). Zlib OR Apache-2.0 OR MIT; objc2-core-foundation already comes with
|
|
# objc2-foundation.
|
|
objc2-core-foundation = { version = "0.3", default-features = false, features = ["std", "CFArray", "CFString", "CFURL"] }
|
|
objc2-core-text = { version = "0.3", default-features = false, features = ["std", "CTFontManager"] }
|
|
# Waits for the answer of a file dialog shown as a sheet (src/main.rs, #867). MIT OR Apache-2.0,
|
|
# already in the build through eframe.
|
|
pollster = "1"
|
|
|
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
# GNOME/Wayland needs client-side window controls without a bundled title font.
|
|
winit = { version = "0.30", default-features = false, features = ["wayland-csd-adwaita-notitle"] }
|
|
|
|
# Asks the Wayland compositor which GPU it draws with (linux-dmabuf feedback, src/compositor_gpu.rs),
|
|
# so Automatic draws on that one. Both are already in the build through winit.
|
|
wayland-client = "0.31"
|
|
wayland-protocols = { version = "0.32", features = ["client", "unstable"] }
|
|
# The save dialog's parent window on Wayland (src/portal_save.rs): an xdg-foreign handle (in
|
|
# wayland-protocols' `unstable` set) made on the window's own connection. MIT, already in the build
|
|
# through winit and rfd.
|
|
wayland-backend = { version = "0.3", features = ["client_system"] }
|
|
|
|
# The save dialog's file type (src/portal_save.rs, #2679): the desktop portal over D-Bus, on the
|
|
# systems where rfd shows the portal's dialog. MIT, already in the build through accesskit. Pinned
|
|
# exactly: review the diff before bumping.
|
|
[target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd", target_os = "openbsd"))'.dependencies]
|
|
zbus = "=5.19.0"
|
|
|
|
[build-dependencies]
|
|
# Icon + VERSIONINFO for vectorcraft.exe; build.rs only uses it when targeting Windows.
|
|
winresource = "0.1"
|
|
|
|
[dev-dependencies]
|
|
# Bound socket buffers in real loopback transport deadline regressions.
|
|
socket2 = { workspace = true }
|
|
# src/portal_save.rs's tests build and read the portal's D-Bus values on every system.
|
|
zbus = "=5.19.0"
|