ics_core/raw.rs
1//! Raw property and component preservation types for ADR-001 round-trip.
2//!
3//! `RawProperty` stores prefix-unmatched `X-*` properties (and, after later
4//! migration steps, vendor-prefix-matched but not-yet-typed properties).
5//! Values are kept verbatim — no escape decoding — because we don't know
6//! what value type rules apply to an unknown property.
7//!
8//! `source_index` is the monotonic input order; ADR-018 specifies that
9//! the formatter emits `unknown` properties at the end of their component,
10//! sorted by `source_index`, so the round-trip preserves the relative
11//! ordering of unknowns even if their absolute position drifts past the
12//! canonical-order typed fields.
13
14use serde::Serialize;
15
16/// A component (`BEGIN:NAME ... END:NAME`) that the typed model does not
17/// understand, preserved verbatim for ADR-001 / ADR-018 round-trip.
18///
19/// Examples: `VTIMEZONE` at the calendar level, `VALARM` nested inside a
20/// `VEVENT`. Nested unknown components are stored recursively in
21/// `sub_components`.
22#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
23pub struct RawComponent {
24 /// Component name, UPPERCASE-normalized (e.g. `VTIMEZONE`, `VALARM`).
25 pub name: String,
26
27 /// All properties of this component as `RawProperty` instances.
28 pub properties: Vec<RawProperty>,
29
30 /// Nested unknown sub-components (e.g. `STANDARD` / `DAYLIGHT` inside
31 /// a `VTIMEZONE`).
32 pub sub_components: Vec<RawComponent>,
33}
34
35#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
36pub struct RawProperty {
37 /// Property name, normalized to UPPERCASE.
38 pub name: String,
39
40 /// Parameter list as `(KEY, value)` pairs. Keys are UPPERCASE-normalized;
41 /// values keep their original casing. Order is preserved from the input.
42 pub params: Vec<(String, String)>,
43
44 /// Raw property value, escapes intact.
45 pub value: String,
46
47 /// 1-based monotonic input order within the enclosing component. ADR-018
48 /// uses this for canonical output ordering.
49 pub source_index: u32,
50}