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