1use crate::{
2 Declaration, DeclarationValue, Diagnostic, Kind, KindSet, NodeMetadata, NodeWithMetadata, Parse, Parser, Peek,
3 Result, Span, T, ToCursors, ToSpan, token_macros,
4};
5use bumpalo::collections::Vec;
6
7#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
29pub struct DeclarationRuleList<'a, D, R, M>
30where
31 D: DeclarationValue<'a, M>,
32 R: NodeWithMetadata<M>,
33 M: NodeMetadata,
34{
35 pub open_curly: token_macros::LeftCurly,
36 pub declarations: Vec<'a, Declaration<'a, D, M>>,
37 pub at_rules: Vec<'a, R>,
38 pub close_curly: Option<token_macros::RightCurly>,
39 meta: M,
40}
41
42impl<'a, D, R, M> NodeWithMetadata<M> for DeclarationRuleList<'a, D, R, M>
43where
44 D: DeclarationValue<'a, M>,
45 R: NodeWithMetadata<M>,
46 M: NodeMetadata,
47{
48 fn metadata(&self) -> M {
49 self.meta
50 }
51}
52
53impl<'a, D, R, M> Peek<'a> for DeclarationRuleList<'a, D, R, M>
54where
55 D: DeclarationValue<'a, M>,
56 R: NodeWithMetadata<M>,
57 M: NodeMetadata,
58{
59 const PEEK_KINDSET: KindSet = KindSet::new(&[Kind::LeftCurly]);
60}
61
62impl<'a, D, R, M> Parse<'a> for DeclarationRuleList<'a, D, R, M>
63where
64 D: DeclarationValue<'a, M>,
65 R: NodeWithMetadata<M> + Parse<'a>,
66 M: NodeMetadata,
67 Declaration<'a, D, M>: Parse<'a>,
68{
69 fn parse<Iter>(p: &mut Parser<'a, Iter>) -> Result<Self>
70 where
71 Iter: Iterator<Item = crate::Cursor> + Clone,
72 {
73 let open_curly = p.parse::<T!['{']>()?;
74 let mut declarations = Vec::new_in(p.bump());
75 let mut at_rules = Vec::new_in(p.bump());
76 let mut meta = Default::default();
77 loop {
78 if p.at_end() {
79 return Ok(Self { open_curly, declarations, at_rules, meta, close_curly: None });
80 }
81 let close_curly = p.parse_if_peek::<T!['}']>()?;
82 if close_curly.is_some() {
83 return Ok(Self { open_curly, declarations, at_rules, meta, close_curly });
84 }
85 let c = p.peek_n(1);
86 if <T![AtKeyword]>::peek(p, c) {
87 at_rules.push(p.parse::<R>()?);
88 } else if <T![Ident]>::peek(p, c) {
89 let rule = p.parse::<Declaration<'a, D, M>>()?;
90 meta.merge(&rule.metadata());
91 declarations.push(rule);
92 } else {
93 Err(Diagnostic::new(p.next(), Diagnostic::unexpected))?;
94 }
95 }
96 }
97}
98
99impl<'a, D, R, M> ToCursors for DeclarationRuleList<'a, D, R, M>
100where
101 D: DeclarationValue<'a, M> + ToCursors,
102 R: NodeWithMetadata<M> + ToCursors,
103 M: NodeMetadata,
104{
105 fn to_cursors(&self, s: &mut impl crate::CursorSink) {
106 ToCursors::to_cursors(&self.open_curly, s);
107 ToCursors::to_cursors(&self.declarations, s);
108 ToCursors::to_cursors(&self.at_rules, s);
109 ToCursors::to_cursors(&self.close_curly, s);
110 }
111}
112
113impl<'a, D, R, M> ToSpan for DeclarationRuleList<'a, D, R, M>
114where
115 D: DeclarationValue<'a, M> + ToSpan,
116 R: NodeWithMetadata<M> + ToSpan,
117 M: NodeMetadata,
118{
119 fn to_span(&self) -> Span {
120 self.open_curly.to_span()
121 + if let Some(close) = self.close_curly {
122 close.to_span()
123 } else {
124 self.declarations.to_span() + self.at_rules.to_span()
125 }
126 }
127}