css_parse/syntax/
declaration_list.rs1use super::prelude::*;
2use crate::{Declaration, token_macros};
3
4#[node]
22#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
23#[cfg_attr(feature = "serde", derive(serde::Serialize))]
24#[cfg_attr(feature = "serde", serde(bound(serialize = "V: serde::Serialize")))]
25pub struct DeclarationList<'a, V, M>
26where
27 V: DeclarationValue<'a, M>,
28 M: NodeMetadata,
29{
30 pub open_curly: token_macros::LeftCurly,
31 pub declarations: Vec<'a, Declaration<'a, V, M>>,
32 pub close_curly: Option<token_macros::RightCurly>,
33 #[cfg_attr(feature = "serde", serde(skip))]
34 meta: M,
35}
36
37impl<'a, V, M> NodeWithMetadata<M> for DeclarationList<'a, V, M>
38where
39 V: DeclarationValue<'a, M>,
40 M: NodeMetadata,
41{
42 fn metadata(&self) -> M {
43 self.meta
44 }
45}
46
47impl<'a, V, M> Peek<'a> for DeclarationList<'a, V, M>
48where
49 V: DeclarationValue<'a, M>,
50 M: NodeMetadata,
51{
52 const PEEK_KINDSET: KindSet = KindSet::new(&[Kind::LeftCurly]);
53}
54
55impl<'a, V, M> Parse<'a> for DeclarationList<'a, V, M>
56where
57 V: DeclarationValue<'a, M>,
58 M: NodeMetadata,
59{
60 fn parse<Iter>(p: &mut Parser<'a, Iter>) -> Result<Self>
61 where
62 Iter: Iterator<Item = crate::Cursor> + Clone,
63 {
64 let nested = p.is(State::Nested);
65 let open_curly = p.parse::<T!['{']>()?;
66 let mut declarations = Vec::new_in(p.alloc());
67 let mut meta: M = Default::default();
68 if nested {
69 meta = meta.with_nested();
70 }
71 loop {
72 if p.at_end() {
73 meta = meta.with_size(declarations.len().min(u16::MAX as usize) as u16);
74 return Ok(Self { open_curly, declarations, close_curly: None, meta });
75 }
76 let close_curly = p.parse_if_peek::<T!['}']>()?;
77 if close_curly.is_some() {
78 meta = meta.with_size(declarations.len().min(u16::MAX as usize) as u16);
79 return Ok(Self { open_curly, declarations, close_curly, meta });
80 }
81 let declaration = p.parse::<Declaration<'a, V, M>>()?;
82 meta = meta.merge(declaration.metadata());
83 declarations.push(declaration);
84 }
85 }
86}
87
88impl<'a, V, M> ToCursors for DeclarationList<'a, V, M>
89where
90 V: DeclarationValue<'a, M> + ToCursors,
91 M: NodeMetadata,
92{
93 fn to_cursors(&self, s: &mut impl CursorSink) {
94 ToCursors::to_cursors(&self.open_curly, s);
95 ToCursors::to_cursors(&self.declarations, s);
96 ToCursors::to_cursors(&self.close_curly, s);
97 }
98}
99
100impl<'a, V, M> ToSpan for DeclarationList<'a, V, M>
101where
102 V: DeclarationValue<'a, M> + ToSpan,
103 M: NodeMetadata,
104{
105 fn to_span(&self) -> Span {
106 self.open_curly.to_span()
107 + if let Some(close) = self.close_curly { close.to_span() } else { self.declarations.to_span() }
108 }
109}
110
111impl<'a, V, M> SemanticEq for DeclarationList<'a, V, M>
112where
113 V: DeclarationValue<'a, M>,
114 M: NodeMetadata,
115{
116 fn semantic_eq(&self, other: &Self) -> bool {
117 self.open_curly.semantic_eq(&other.open_curly)
118 && self.declarations.semantic_eq(&other.declarations)
119 && self.close_curly.semantic_eq(&other.close_curly)
120 }
121}