css_parse/traits/node_metadata.rs
1/// Aggregated metadata for nodes, that can propagate up a node tree.
2pub trait NodeMetadata: Sized + Copy + Default {
3 /// Merges another NodeMetadata into this one, returning the result.
4 fn merge(self, other: Self) -> Self;
5
6 /// Sets the size of this metadata (e.g., number of declarations, selector list length).
7 /// Default implementation is a no-op for metadata types that don't track size.
8 fn with_size(self, _size: u16) -> Self {
9 self
10 }
11
12 /// Marks this metadata as describing a declaration.
13 /// Default implementation is a no-op for metadata types that don't track node kinds.
14 fn with_declaration(self) -> Self {
15 self
16 }
17
18 /// Marks this metadata as describing a node nested inside another node.
19 /// Default implementation is a no-op for metadata types that don't track node kinds.
20 fn with_nested(self) -> Self {
21 self
22 }
23}
24
25/// A Node that has NodeMetadata
26pub trait NodeWithMetadata<M: NodeMetadata> {
27 /// Returns the metadata contributed by this node itself, not including children.
28 /// Most nodes don't contribute metadata, so can simply return `M::default()`.
29 /// Nodes like StyleRule or AtRules should return their own node kind flags here.
30 fn self_metadata(&self) -> M {
31 M::default()
32 }
33
34 /// Returns the complete aggregated metadata for this node (self + children).
35 /// Default implementation merges children's metadata with self_metadata().
36 fn metadata(&self) -> M;
37}
38
39// Stub implementation allowing tests to use () for M
40impl NodeMetadata for () {
41 fn merge(self, _: Self) -> Self {}
42}
43
44// Blanket implementation for Option<T> where T: NodeWithMetadata<M>
45// Returns default metadata when None, or delegates to the inner value when Some
46impl<M: NodeMetadata, T: NodeWithMetadata<M>> NodeWithMetadata<M> for Option<T> {
47 fn self_metadata(&self) -> M {
48 match self {
49 Some(inner) => inner.self_metadata(),
50 None => M::default(),
51 }
52 }
53
54 fn metadata(&self) -> M {
55 match self {
56 Some(inner) => inner.metadata(),
57 None => M::default(),
58 }
59 }
60}