feat(calendar): bounded caldav report calendar-query and timezone expansion #42
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/issue-8-caldav-query"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Motivation
Issue #8 requires bounded CalDAV
REPORTcalendar-queryas the authoritative recurrence engine: server-side expansion via<C:expand>, strict half-open[from, to)interval math in a mandatory configured IANA timezone, tagged date/instant representations, and fail-fast enforcement of the 93-day span / 10,000-instance ceilings. An unreachable Radicale must yielddependency_unavailable, never an empty agenda.Changes
src/calendar/timezone.rs:CalendarTimezonewrappingchrono_tz::Tz, parsed strictly from config; invalid IANA strings fail withconfiguration_invalid, no host-timezone fallback.period_today/period_tomorrow/period_weekbuild local-midnight (week: Monday 00:00) boundaries in local calendar time, then convert to UTC; half-open[from, to)throughout.HalfOpenInterval::newenforcesstart < endand the 93-day (MAX_QUERY_SPAN_DAYS) span ceiling, returninglimit_exceededwith a narrow-range instruction.TaggedTime(date/instantserde-tagged), DST fold/gap handling viaresolve_local_datetime: ambiguous fold without an explicit offset orDstChoicereturnsclarification_required; nonexistent gap times are rejected withinvalid_input, never auto-shifted.src/calendar/report.rs:build_calendar_query_xml: RFC 4791calendar-queryenvelope with<D:getetag/>,<C:calendar-data><C:expand start=... end=.../></C:calendar-data>, andVCALENDAR > VEVENT/VTODO > time-rangefilters.parse_report_multistatus: namespace-awarequick-xmlparsing of207 Multi-Status(href, getetag, calendar-data, per-propstat status), with byte-size and depth caps.parse_and_expand_report: RFC 5545 line unfolding, parameter parsing, and normalization intoExpandedComponent(UID, SUMMARY, STATUS, TRANSP, RECURRENCE-ID with TZID identity, DTSTART/DTEND/DUE). All-dayVALUE=DATEtimes keepDTENDexclusive, defaulting a missing DTEND to start+1 day (Scenario C04). Floating datetimes are interpreted in the configured timezone; UTC/TZID datetimes stay tagged instants. Instance ceiling of 10,000 (MAX_EXPANDED_INSTANCES) aborts withlimit_exceeded.execute_calendar_query: dispatches HTTPREPORT(Depth: 1,application/xml) throughCalDavClientand normalizes the result.src/calendar/client.rs: addedreport()next topropfind(); transport errors on connect/timeout map todependency_unavailable(distinct from a successful empty response), 502/503/504 map todependency_unavailable, auth failures toforbidden.src/calendar/mod.rs: error-code/exit-code mappings forlimit_exceeded,dependency_unavailable,clarification_required,configuration_invalid.tests/caldav_report_tests.rs: coverage for W03 period boundaries, C03 DST fold/gap, C04 all-day exclusivity, C08 span + instance ceilings, XML builder shape, multistatus parsing with detached overrides, a full in-process Axum REPORT flow, and C01 empty-agenda-vs-unreachable.Verification
nix develop --command cargo test— all suites pass, including 10 new tests intests/caldav_report_tests.rs(W03, C01, C03, C04, C08 covered).cargo clippy --all-targets -- -D warnings— clean.cargo fmt --check— clean.Related Issues
Closes #8. Builds on #7 (CalDAV connection pooling, PROPFIND discovery).
feat(calendar): bounded caldav report calendar-query and timezone expansion (#8)to feat(calendar): bounded caldav report calendar-query and timezone expansion