Skip to main content

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}