Discovery is the three PROPFINDs RFC 4791 describes rather than a walk through likely URLs. Queries use time-range, which v1 never did -- it fetched whole calendars and filtered in the browser on every view change. Every write states a precondition, so a stale ETag produces a Conflict a caller can act on instead of silently destroying somebody's edit. XML goes through quick-xml with namespace resolution. v1 matched prefixes with six regexes tried in sequence and recompiled inside the loop; there is a fixture here that is the same document under different prefixes, and it parses identically. Protocol parsing is split from transport so it can be tested against responses recorded from a real Baikal -- including the second propstat carrying 404s, which is what makes "this calendar has no colour" different from "this calendar has an empty colour". Live tests run against a real server, never a mock. tests/baikal/run.sh starts a container, walks Baikal's install wizard, and runs them; each test builds and destroys its own collection, so pointing it at a real server touches nothing that was already there. They cover discovery, round-trip, stale-ETag conflict, duplicate create, delete, time-range filtering, a series returned whole with its override, and writing every synthetic golden fixture to the server and reading it back. libdav was evaluated first, as planned. Not adopted: its HttpClient trait is defined over hyper::body::Incoming, so using it means replacing reqwest everywhere, plus a DNS resolver for service discovery we do not do and a second XML parser. Its precondition design is where Precondition's shape comes from. Reasons are recorded in the crate docs.
72 lines
1.7 KiB
TOML
72 lines
1.7 KiB
TOML
[workspace]
|
|
resolver = "3"
|
|
members = [
|
|
"crates/runway-core",
|
|
"crates/runway-caldav",
|
|
"crates/runway-server",
|
|
"crates/runway-web",
|
|
"crates/runway-cli",
|
|
]
|
|
|
|
[workspace.package]
|
|
version = "0.1.0"
|
|
edition = "2024"
|
|
license = "MIT"
|
|
repository = "https://github.com/connorjohnstone/runway"
|
|
|
|
[workspace.lints.rust]
|
|
dead_code = "deny"
|
|
unused_must_use = "deny"
|
|
unsafe_code = "forbid"
|
|
|
|
[workspace.lints.clippy]
|
|
# v1 had 65 of these. Tests opt out locally.
|
|
unwrap_used = "deny"
|
|
expect_used = "deny"
|
|
|
|
[workspace.dependencies]
|
|
# Internal
|
|
runway-core = { path = "crates/runway-core" }
|
|
runway-caldav = { path = "crates/runway-caldav" }
|
|
|
|
# Core data
|
|
chrono = { version = "0.4", default-features = false, features = ["serde", "clock", "std"] }
|
|
chrono-tz = { version = "0.10", features = ["serde"] }
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
uuid = { version = "1", features = ["v4", "serde"] }
|
|
|
|
# Calendar domain
|
|
icalendar = "0.17"
|
|
rrule = "0.14"
|
|
|
|
# Errors + logging
|
|
thiserror = "2"
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
|
|
# Backend
|
|
axum = "0.8"
|
|
tokio = { version = "1", features = ["rt-multi-thread", "macros", "net", "signal"] }
|
|
tower = "0.5"
|
|
tower-http = { version = "0.6", features = ["cors", "trace"] }
|
|
sqlx = { version = "0.9", features = ["runtime-tokio", "sqlite", "chrono", "uuid", "migrate"] }
|
|
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
|
|
quick-xml = "0.42"
|
|
|
|
# Frontend
|
|
leptos = "0.8"
|
|
leptos_router = "0.8"
|
|
|
|
# CLI
|
|
clap = { version = "4", features = ["derive", "env"] }
|
|
|
|
# Dev
|
|
pretty_assertions = "1"
|
|
|
|
[profile.release]
|
|
opt-level = "z"
|
|
lto = true
|
|
codegen-units = 1
|
|
strip = true
|