Skip to main content

ical/tree/prop/
lens.rs

1//! # Property lens contract
2//!
3//! [`IcalPropLens`] ties a property (by type) to its decoded value type, an
4//! edit cursor, and the `decode` projection from the generic syntax node onto
5//! the type.
6//!
7//! The wire name comes from its [`IcalPropSpec::KIND`] supertrait, so the two
8//! stay in sync; each property implements it on the marker it defines in
9//! [`crate::prop`].
10
11use crate::{
12    prop::spec::IcalPropSpec,
13    tree::{codec::Codec, line::IcalLine},
14    version::IcalVersion,
15};
16
17/// A property identified by type: its decoded value type, edit cursor, and the
18/// `decode` projection from the generic syntax node onto the type. The wire
19/// name comes from its [`IcalPropSpec::KIND`] (a supertrait), so the two stay
20/// in sync.
21pub trait IcalPropLens: IcalPropSpec {
22    /// The decoded value type, borrowing the syntax node for reads. Its
23    /// [`Codec`] impl is what the default `decode` delegates to.
24    type Target<'v>: Codec<'v>;
25
26    /// The typed edit cursor over a content line.
27    type Cursor<'c, 'a>
28    where
29        'a: 'c;
30
31    /// Project a content line onto the decoded type, consulting the calendar
32    /// version where the value's shape is version-specific (`GEO`, the binary
33    /// props). The default ignores the version and decodes the value node
34    /// through the target's [`Codec`]; the version-specific lenses override it.
35    fn decode<'v>(line: &'v IcalLine<'_>, _version: IcalVersion) -> Self::Target<'v> {
36        <Self::Target<'v> as Codec<'v>>::decode(&line.value)
37    }
38
39    /// Wrap a content line in the typed cursor for in-place editing.
40    fn cursor<'c, 'a>(line: &'c mut IcalLine<'a>) -> Self::Cursor<'c, 'a>;
41}