Expand description
JSCalendar (RFC 8984) typed sub-types for the jmap-* crate family.
Normative reference: RFC 8984 (JSCalendar).
These are sub-object types that have no JMAP identity of their own.
They are embedded within CalendarEvent (from jmap-calendars-types),
Task (from jmap-tasks-types), and other JMAP objects.
§Crate family position
jmap-types (RFC 8620 wire primitives)
└── jmap-jscalendar-types ← this crate (RFC 8984 typed sub-types)
├── jmap-calendars-types (consumes via path-dep + re-export)
└── jmap-tasks-types (consumes via path-dep + re-export)§Design: newtype wrappers for scalar temporal values
RFC 8984 §1.4.5 defines LocalDateTime as a string without a timezone
offset (e.g. "2024-06-15T09:00:00"). RFC 8984 §1.4.6 defines Duration
as an ISO 8601-subset string (e.g. "PT1H"). RFC 8984 §1.4.7 defines
SignedDuration as an optional-sign prefix on Duration.
These are modelled as newtype wrappers around String to document intent
at the type level without pulling in a heavy parser dependency. Validation
of internal format is left to the backend.
§Spec-driven divergences (deliberate, do not “fix”)
Three design choices in this crate look like inconsistency at a glance but are deliberate spec-compliance decisions; preserve them against future “consistency” or “simplification” PRs.
-
Bare
Stringat_type(notOption<String>). Diverges from the siblingjmap-jscontact-typeswhich usesOption<String>. Spec authority: RFC 8984 marks every@typediscriminator as(mandatory)with zerodefaultTypeannotations; RFC 9553 §1.3.4 introducesdefaultTypeand permits omitting@typein implied-type positions. Workspace canonical-templates rule explicitly permits “differences mandated by the relevant RFC or draft”. SeePLAN.mdandbd:JMAP-sgrr.3. -
AlertTrigger::Unknown(serde_json::Value). Holds an opaqueValuerather than a typed struct or aString. Spec authority: RFC 8984 §4.5.2 “Implementations MUST NOT trigger for trigger types they do not understand but MUST preserve them.” A typedUnknown(String)would discard the inner fields; a typedUnknown { at_type, fields }would force a schema on what is explicitly unschema’d. The manualDeserializeimpl is required because serde does not support#[serde(tag = "@type", other)]with non-unit tuple variants. SeeAlertTriggerrustdoc. -
serde_json::{Map, Value}in the public API surface. The workspace extras-preservation policy mandates apub extra: serde_json::Map<String, serde_json::Value>field on every wire-format struct, andAlertTrigger::Unknowncarries a rawValue. This locks the crate’s major version toserde_json’s, which is the explicit trade-off: round-trip fidelity for vendor / site / private fields outweighs the coupling cost. SeePLAN.md“Extras-preservation policy” and workspaceAGENTS.md.
§Test-oracle discipline
Test fixtures are constructed from serde_json::json!({...}) literals
whose shape comes directly from RFC 8984 example text. Per workspace
test-integrity rules, the oracle MUST be the spec example, NOT the code
under test. Do NOT replace fixture construction with “build a typed
struct, serialize, deserialize, compare” — that pattern uses the code
under test as its own oracle.
Structs§
- Absolute
Trigger - A trigger time given as an absolute UTC date-time (RFC 8984 §4.5.2).
- Alert
- An alert to be shown or emailed before or after an event (RFC 8984 §4.5.2).
- Duration
- An ISO 8601 duration string (RFC 8984 §1.4.6).
- Id
- Opaque non-empty server-assigned identifier (RFC 8620 §1.2).
- Link
- An attachment, image, or URL associated with an event (RFC 8984 §1.4.11).
- Local
Date Time - A date-time string without a timezone offset (RFC 8984 §1.4.5).
- Location
- A physical or virtual location associated with an event (RFC 8984 §4.2.5).
- NDay
- The
nthOfPeriodfield of anNDayentry (RFC 8984 §4.3.3). - Offset
Trigger - A trigger time given as an offset from the event start or end (RFC 8984 §4.5.2).
- Participant
- A participant in an event (RFC 8984 §4.4.6).
- Patch
Object - A JMAP
PatchObject(RFC 8620 §5.3) — a String → JSON map describing the changes to apply to a record during*/setupdate. - Recurrence
Rule - A recurrence rule as defined in RFC 8984 §4.3.3.
- Relation
- A relationship between this object and another, identified by UID (RFC 8984 §1.4.10).
- Signed
Duration - A signed ISO 8601 duration string (RFC 8984 §1.4.7).
- Time
Zone - A time-zone definition embedded in
CalendarEvent.timeZonesorTask.timeZones(RFC 8984 §4.7.2). - Time
Zone Rule - A STANDARD or DAYLIGHT sub-component of a
TimeZone(RFC 8984 §4.7.2). - Type
TagMismatch - Mismatch between an object’s
at_typewire string and the RFC 8984-mandated discriminator literal for its Rust type. - UTCDate
- RFC 3339 UTC timestamp string (RFC 8620 §1.4).
- UTCOffset
- A UTC offset string (RFC 5545 / RFC 8984 §4.7.2 — the TZOFFSETFROM / TZOFFSETTO format).
- Virtual
Location - An online meeting or virtual location (RFC 8984 §4.2.6).
Enums§
- Alert
Trigger - Alert trigger — either offset-based, absolute, or an unknown future type (RFC 8984 §4.5.2).
- Link
Source Error - Error returned by
Link::validate_sourcewhen the source invariant (RFC 8984 §1.4.11 + JMAP Calendars draft §5.3) is violated. - Participant
Roles Error - Error returned by
Participant::validate_roleswhen the RFC 8984 §4.4.6 non-empty-roles invariant is violated. - Recurrence
Overrides Error - Error returned by
TimeZoneRule::validate_recurrence_overrides_emptywhen the RFC 8984 §4.7.2 “PatchObject value MUST be the empty patch” constraint is violated.
Traits§
- Type
Discriminator - Wire-format type-tag discriminator for JSCalendar sub-objects (RFC 8984).