1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//! # Parameter lens contract
//!
//! [`IcalParamLens`] ties a wire name to a parameter's decoded shape (a single
//! value or a list); the per-name markers in the sibling modules implement it,
//! and it is the type-level key for
//! [`IcalLine::param`](crate::tree::line::IcalLine::param).
use crate::{param::IcalParamKind, tree::param::node::IcalParamNode};
/// A parameter identified by type, projecting a generic syntax parameter onto a
/// decoded value type and back.
pub trait IcalParamLens {
/// The parameter kind to look up by (its wire name comes through `Deref`).
const KIND: IcalParamKind;
/// The decoded value type, borrowing the syntax node for reads.
type Target<'v>;
/// Project the generic syntax parameter onto the decoded type.
fn decode<'v>(param: &'v IcalParamNode<'_>) -> Self::Target<'v>;
/// Encode a decoded value back into a generic syntax parameter (owned).
fn encode(decoded: &Self::Target<'_>) -> IcalParamNode<'static>;
}
#[cfg(test)]
mod tests {
use alloc::{borrow::Cow, string::ToString, vec};
use crate::tree::param::{
language::LANGUAGE, lens::IcalParamLens, member::MEMBER, node::IcalParamNode,
};
#[test]
fn decodes_a_list_parameter_through_its_lens() {
let node = IcalParamNode::parse("MEMBER=a,b");
assert_eq!(
MEMBER::decode(&node),
vec![Cow::Borrowed("a"), Cow::Borrowed("b")],
);
}
#[test]
fn encodes_a_scalar_parameter_through_its_lens() {
let node = LANGUAGE::encode(&Cow::Borrowed("en"));
assert_eq!(node.to_string(), "LANGUAGE=en");
}
}