1use super::prelude::*;
2use crate::{BadDeclaration, Block};
3
4#[node]
5#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize))]
7#[cfg_attr(
8 feature = "serde",
9 serde(bound(serialize = "P: serde::Serialize, D: serde::Serialize, R: serde::Serialize"))
10)]
11pub struct QualifiedRule<'a, P, D, R, M>
12where
13 D: DeclarationValue<'a, M>,
15 M: NodeMetadata,
16{
17 pub prelude: P,
18 pub block: Block<'a, D, R, M>,
19}
20
21impl<'a, P, D, R, M> NodeWithMetadata<M> for QualifiedRule<'a, P, D, R, M>
22where
23 D: DeclarationValue<'a, M>,
24 M: NodeMetadata,
25{
26 fn metadata(&self) -> M {
27 self.block.metadata()
28 }
29}
30
31impl<'a, P, D, R, M> Peek<'a> for QualifiedRule<'a, P, D, R, M>
32where
33 P: Peek<'a>,
34 D: DeclarationValue<'a, M>,
35 M: NodeMetadata,
36{
37 const PEEK_KINDSET: KindSet = P::PEEK_KINDSET;
38}
39
40impl<'a, P, D, R, M> Parse<'a> for QualifiedRule<'a, P, D, R, M>
44where
45 D: DeclarationValue<'a, M>,
46 P: Parse<'a>,
47 R: Parse<'a> + NodeWithMetadata<M> + crate::RuleVariants<'a, DeclarationValue = D, Metadata = M>,
48 M: NodeMetadata,
49{
50 fn parse<Iter>(p: &mut Parser<'a, Iter>) -> Result<Self>
51 where
52 Iter: Iterator<Item = crate::Cursor> + Clone,
53 {
54 let c = p.peek_n(1);
55 if p.at_end() {
63 Err(Diagnostic::new(p.peek_n(1), Diagnostic::unexpected_end))?
64 }
65
66 if p.is(State::Nested) && <T!['}']>::peek(p, c) {
69 Err(Diagnostic::new(c, Diagnostic::unexpected_close_curly))?;
70 }
71
72 let checkpoint = p.checkpoint();
75 if <T![DashedIdent]>::peek(p, c) {
76 p.parse::<T![DashedIdent]>().ok();
77 if <T![:]>::peek(p, p.peek_n(1)) {
78 if p.is(State::Nested) {
80 p.rewind(checkpoint.clone());
81 let start = p.peek_n(1);
82 p.parse::<BadDeclaration>()?;
83 let end = p.peek_n(1);
84 Err(Diagnostic::new(start, Diagnostic::bad_declaration).with_end_cursor(end))?
85 } else {
87 p.parse::<Block<'a, D, R, M>>()?;
93 let start = p.peek_n(1);
94 p.parse::<BadDeclaration>()?;
95 let end = p.peek_n(1);
96 Err(Diagnostic::new(start, Diagnostic::bad_declaration).with_end_cursor(end))?
97 }
98 }
99 p.rewind(checkpoint);
100 }
101
102 let old_stop = p.set_stop(KindSet::new(&[Kind::LeftCurly]));
104 let prelude = p.parse::<P>();
105 p.set_stop(old_stop);
106 let prelude = prelude?;
107
108 let block = p.parse::<Block<'a, D, R, M>>()?;
115 Ok(Self { prelude, block })
116 }
117}
118
119impl<'a, P, D, R, M> ToCursors for QualifiedRule<'a, P, D, R, M>
120where
121 D: DeclarationValue<'a, M> + ToCursors,
122 P: ToCursors,
123 R: ToCursors,
124 M: NodeMetadata,
125{
126 fn to_cursors(&self, s: &mut impl CursorSink) {
127 ToCursors::to_cursors(&self.prelude, s);
128 ToCursors::to_cursors(&self.block, s);
129 }
130}
131
132impl<'a, P, D, R, M> ToSpan for QualifiedRule<'a, P, D, R, M>
133where
134 D: DeclarationValue<'a, M> + ToSpan,
135 P: ToSpan,
136 R: ToSpan,
137 M: NodeMetadata,
138{
139 fn to_span(&self) -> Span {
140 self.prelude.to_span() + self.block.to_span()
141 }
142}
143
144impl<'a, P, D, R, M> SemanticEq for QualifiedRule<'a, P, D, R, M>
145where
146 D: DeclarationValue<'a, M> + SemanticEq,
147 P: SemanticEq,
148 R: SemanticEq,
149 M: NodeMetadata,
150{
151 fn semantic_eq(&self, other: &Self, source_text: &str) -> bool {
152 self.prelude.semantic_eq(&other.prelude, source_text) && self.block.semantic_eq(&other.block, source_text)
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use super::*;
159 use crate::{Cursor, EmptyAtomSet, test_helpers::*};
160
161 #[derive(Debug)]
162 struct Decl(T![Ident]);
163
164 impl NodeWithMetadata<()> for Decl {
165 fn metadata(&self) {}
166 }
167
168 impl<'a> DeclarationValue<'a, ()> for Decl {
169 fn parse_specified_declaration_value<Iter>(p: &mut Parser<'a, Iter>, _: Cursor) -> Result<Self>
170 where
171 Iter: Iterator<Item = crate::Cursor> + Clone,
172 {
173 p.parse::<T![Ident]>().map(Self)
174 }
175 }
176
177 impl ToCursors for Decl {
178 fn to_cursors(&self, s: &mut impl CursorSink) {
179 ToCursors::to_cursors(&self.0, s);
180 }
181 }
182
183 impl ToSpan for Decl {
184 fn to_span(&self) -> Span {
185 self.0.to_span()
186 }
187 }
188
189 impl SemanticEq for Decl {
190 fn semantic_eq(&self, other: &Self, source_text: &str) -> bool {
191 self.0.semantic_eq(&other.0, source_text)
192 }
193 }
194
195 #[derive(Debug)]
196 struct Rule(T![Ident]);
197
198 impl<'a> Parse<'a> for Rule {
199 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
200 where
201 I: Iterator<Item = Cursor> + Clone,
202 {
203 Ok(Self(p.parse::<T![Ident]>()?))
204 }
205 }
206
207 impl ToCursors for Rule {
208 fn to_cursors(&self, s: &mut impl CursorSink) {
209 ToCursors::to_cursors(&self.0, s);
210 }
211 }
212
213 impl ToSpan for Rule {
214 fn to_span(&self) -> Span {
215 self.0.to_span()
216 }
217 }
218
219 impl NodeWithMetadata<()> for Rule {
220 fn metadata(&self) {}
221 }
222
223 impl<'a> crate::RuleVariants<'a> for Rule {
224 type DeclarationValue = Decl;
225 type Metadata = ();
226 }
227
228 #[test]
229 fn test_writes() {
230 assert_parse!(EmptyAtomSet::ATOMS, QualifiedRule<T![Ident], Decl, Rule, ()>, "body{color:black}");
231 }
232}