1include!(concat!(env!("OUT_DIR"), "/css_node_kind.rs"));
2include!(concat!(env!("OUT_DIR"), "/css_apply_visit_methods.rs"));
3
4use css_parse::Vec;
5use css_parse::{
6 Block, Box, CommaSeparated, Comparison, ComponentValue, ComponentValues, Cursor, Declaration, DeclarationGroup,
7 DeclarationList, DeclarationOrBad, DeclarationValue, Either, NoBlockAllowed, NodeMetadata, NodeWithMetadata,
8 Optionals2, Optionals3, Optionals4, Optionals5, Parse, Peek, QualifiedRule, RuleList, ToCursors, ToSpan,
9 syntax::BadDeclaration, token_macros,
10};
11use visit_flow::{VisitFlow, try_visit};
12
13pub use csskit_derives::visitor;
16pub use visit_flow::{VisitAction, VisitBreak, VisitFlowExt};
17
18mod root;
19mod visit_node;
20pub use root::{ErasedNode, ParsedRoot, parse_root};
21pub(crate) use visit_node::QueryNodeData;
22pub use visit_node::{NodeKey, VisitNode};
23
24use crate::*;
25
26macro_rules! visit_mut_trait {
27 ( $(
28 $name: ident$(<$($gen:tt),+>)?($obj: ty),
29 )+ ) => {
30 pub trait VisitMut: Sized {
31 fn visit_declaration<'a, T: DeclarationValue<'a, CssMetadata>>(&mut self, _rule: &mut Declaration<'a, T, CssMetadata>) {}
32 fn exit_declaration<'a, T: DeclarationValue<'a, CssMetadata>>(&mut self, _rule: &mut Declaration<'a, T, CssMetadata>) {}
33 fn visit_bad_declaration<'a>(&mut self, _rule: &mut BadDeclaration<'a>) {}
34 fn exit_bad_declaration<'a>(&mut self, _rule: &mut BadDeclaration<'a>) {}
35 fn visit_string(&mut self, _str: &mut token_macros::String) {}
36 fn exit_string(&mut self, _str: &mut token_macros::String) {}
37 fn visit_comparison(&mut self, _comparison: &mut Comparison) {}
38 fn exit_comparison(&mut self, _comparison: &mut Comparison) {}
39 $(
40 fn $name$(<$($gen),+>)?(&mut self, _rule: &mut $obj) {}
41 )+
42 }
43 }
44}
45apply_visit_methods!(visit_mut_trait);
46
47pub trait NodeVisitor {
54 fn consider_node(&self, node: VisitNode) -> VisitFlow;
59
60 fn enter_node(&mut self, node: VisitNode) -> VisitFlow;
65
66 fn exit_node(&mut self, node: VisitNode) -> VisitFlow;
68}
69
70impl NodeVisitor for &mut (dyn NodeVisitor + '_) {
71 fn consider_node(&self, node: VisitNode) -> VisitFlow {
72 (**self).consider_node(node)
73 }
74
75 fn enter_node(&mut self, node: VisitNode) -> VisitFlow {
76 (**self).enter_node(node)
77 }
78
79 fn exit_node(&mut self, node: VisitNode) -> VisitFlow {
80 (**self).exit_node(node)
81 }
82}
83
84impl Visit for &mut (dyn NodeVisitor + '_) {}
85
86macro_rules! visit_trait {
87 ( $(
88 $name: ident$(<$($gen:tt),+>)?($obj: ty),
89 )+ ) => {
90 pub trait Visit: NodeVisitor + Sized {
91
92 fn enter_declaration<'a, T: DeclarationValue<'a, CssMetadata>>(&mut self, _rule: &Declaration<'a, T, CssMetadata>, _node: VisitNode) -> VisitFlow {
93 VisitFlow::DESCEND
94 }
95 fn exit_declaration<'a, T: DeclarationValue<'a, CssMetadata>>(&mut self, _rule: &Declaration<'a, T, CssMetadata>, _node: VisitNode) -> VisitFlow {
96 VisitFlow::DESCEND
97 }
98 fn visit_bad_declaration<'a>(&mut self, _rule: &BadDeclaration<'a>) -> VisitFlow {
99 VisitFlow::DESCEND
100 }
101 fn exit_bad_declaration<'a>(&mut self, _rule: &BadDeclaration<'a>) -> VisitFlow {
102 VisitFlow::DESCEND
103 }
104 fn visit_string(&mut self, _str: &token_macros::String) -> VisitFlow {
105 VisitFlow::DESCEND
106 }
107 fn exit_string(&mut self, _str: &token_macros::String) -> VisitFlow {
108 VisitFlow::DESCEND
109 }
110 fn visit_comparison(&mut self, _comparison: &Comparison) -> VisitFlow {
111 VisitFlow::DESCEND
112 }
113 fn exit_comparison(&mut self, _comparison: &Comparison) -> VisitFlow {
114 VisitFlow::DESCEND
115 }
116
117 fn visit_feature<T: FeatureMetadata>(&mut self, _node: &T) {}
118 fn exit_feature<T: FeatureMetadata>(&mut self, _node: &T) {}
119
120 $(
121 fn $name$(<$($gen),+>)?(&mut self, _rule: &$obj) -> VisitFlow {
122 VisitFlow::DESCEND
123 }
124 )+
125 }
126 }
127}
128apply_visit_methods!(visit_trait);
129
130pub trait VisitableMut {
131 fn accept_mut<V: VisitMut>(&mut self, v: &mut V);
132}
133
134pub trait Visitable {
135 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow;
136}
137
138pub(crate) trait QueryableNode: ToSpan + NodeWithMetadata<CssMetadata> {
144 const NODE_ID: NodeId;
146
147 fn get_property(&self, _kind: PropertyKind) -> Option<Cursor> {
153 None
154 }
155
156 fn visit_node(&self) -> VisitNode<'_>
161 where
162 Self: Sized,
163 {
164 VisitNode::new(self.to_span(), Self::NODE_ID, self)
165 }
166}
167
168impl<T: QueryableNode> QueryNodeData for T {
170 #[inline]
171 fn self_metadata(&self) -> CssMetadata {
172 NodeWithMetadata::self_metadata(self)
173 }
174 #[inline]
175 fn subtree_metadata(&self) -> CssMetadata {
176 NodeWithMetadata::metadata(self)
177 }
178 #[inline]
179 fn get_property(&self, kind: PropertyKind) -> Option<Cursor> {
180 QueryableNode::get_property(self, kind)
181 }
182}
183
184impl<T> VisitableMut for Option<T>
185where
186 T: VisitableMut,
187{
188 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
189 if let Some(node) = self {
190 node.accept_mut(v)
191 }
192 }
193}
194
195macro_rules! impl_optionals {
196 ($N:ident, $($T:ident),+) => {
197 impl<$($T),*> Visitable for $N<$($T),+>
198 where
199 $($T: Visitable,)+
200 {
201 #[allow(non_snake_case)]
202 #[allow(unused)]
203 fn accept<VI: Visit>(&self, v: &mut VI) -> VisitFlow {
204 let $N($($T),+) = self;
205 $(try_visit!($T.accept(v));)+;
206 VisitFlow::DESCEND
207 }
208 }
209
210 impl<$($T),*> VisitableMut for $N<$($T),+>
211 where
212 $($T: VisitableMut,)+
213 {
214 #[allow(non_snake_case)]
215 #[allow(unused)]
216 fn accept_mut<VI: VisitMut>(&mut self, v: &mut VI) {
217 let $N($($T),+) = self;
218 $($T.accept_mut(v);)+;
219 }
220 }
221 };
222}
223
224impl_optionals!(Optionals2, T, U);
225impl_optionals!(Optionals3, T, U, V);
226impl_optionals!(Optionals4, T, U, V, W);
227impl_optionals!(Optionals5, T, U, V, W, X);
228
229impl Visitable for token_macros::Ident {
230 fn accept<V: Visit>(&self, _: &mut V) -> VisitFlow {
231 VisitFlow::DESCEND
232 }
233}
234
235impl VisitableMut for token_macros::Ident {
236 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
237}
238
239impl Visitable for token_macros::Function {
240 fn accept<V: Visit>(&self, _: &mut V) -> VisitFlow {
241 VisitFlow::DESCEND
242 }
243}
244
245impl VisitableMut for token_macros::Function {
246 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
247}
248
249impl Visitable for token_macros::Comma {
250 fn accept<V: Visit>(&self, _: &mut V) -> VisitFlow {
251 VisitFlow::DESCEND
252 }
253}
254
255impl VisitableMut for token_macros::Comma {
256 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
257}
258
259impl Visitable for token_macros::LeftParen {
260 fn accept<V: Visit>(&self, _: &mut V) -> VisitFlow {
261 VisitFlow::DESCEND
262 }
263}
264
265impl VisitableMut for token_macros::LeftParen {
266 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
267}
268
269impl Visitable for token_macros::RightParen {
270 fn accept<V: Visit>(&self, _: &mut V) -> VisitFlow {
271 VisitFlow::DESCEND
272 }
273}
274
275impl VisitableMut for token_macros::RightParen {
276 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
277}
278
279impl Visitable for token_macros::Colon {
280 fn accept<V: Visit>(&self, _: &mut V) -> VisitFlow {
281 VisitFlow::DESCEND
282 }
283}
284
285impl VisitableMut for token_macros::Colon {
286 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
287}
288
289impl Visitable for token_macros::Semicolon {
290 fn accept<V: Visit>(&self, _: &mut V) -> VisitFlow {
291 VisitFlow::DESCEND
292 }
293}
294
295impl VisitableMut for token_macros::Semicolon {
296 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
297}
298
299impl Visitable for Comparison {
300 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
301 try_visit!(v.visit_comparison(self));
302 try_visit!(v.exit_comparison(self));
303 VisitFlow::DESCEND
304 }
305}
306
307impl VisitableMut for Comparison {
308 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
309 v.visit_comparison(self);
310 v.exit_comparison(self);
311 }
312}
313
314impl Visitable for token_macros::delim::Dash {
315 fn accept<V: Visit>(&self, _: &mut V) -> VisitFlow {
316 VisitFlow::DESCEND
317 }
318}
319
320impl VisitableMut for token_macros::delim::Dash {
321 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
322}
323
324impl Visitable for token_macros::delim::Slash {
325 fn accept<V: Visit>(&self, _: &mut V) -> VisitFlow {
326 VisitFlow::DESCEND
327 }
328}
329
330impl VisitableMut for token_macros::delim::Slash {
331 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
332}
333
334impl Visitable for token_macros::Number {
335 fn accept<V: Visit>(&self, _: &mut V) -> VisitFlow {
336 VisitFlow::DESCEND
337 }
338}
339
340impl VisitableMut for token_macros::Number {
341 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
342}
343
344impl Visitable for token_macros::Any {
345 fn accept<V: Visit>(&self, _: &mut V) -> VisitFlow {
346 VisitFlow::DESCEND
347 }
348}
349
350impl VisitableMut for token_macros::Any {
351 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
352}
353
354impl Visitable for token_macros::String {
355 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
356 try_visit!(v.visit_string(self));
357 try_visit!(v.exit_string(self));
358 VisitFlow::DESCEND
359 }
360}
361
362impl VisitableMut for token_macros::String {
363 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
364 v.visit_string(self);
365 v.exit_string(self);
366 }
367}
368
369impl<T> Visitable for Option<T>
370where
371 T: Visitable,
372{
373 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
374 if let Some(node) = self {
375 try_visit!(node.accept(v));
376 }
377 VisitFlow::DESCEND
378 }
379}
380
381impl<'a, T: VisitableMut> VisitableMut for Box<'a, T> {
382 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
383 (**self).accept_mut(v)
384 }
385}
386
387impl<'a, T: Visitable> Visitable for Box<'a, T> {
388 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
389 (**self).accept(v)
390 }
391}
392
393impl<'a, T, const MIN: usize> VisitableMut for CommaSeparated<'a, T, MIN>
394where
395 T: VisitableMut,
396{
397 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
398 for (node, _) in self {
399 node.accept_mut(v)
400 }
401 }
402}
403
404impl<'a, T, const MIN: usize> Visitable for CommaSeparated<'a, T, MIN>
405where
406 T: Visitable,
407{
408 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
409 for (node, _) in self {
410 try_visit!(node.accept(v));
411 }
412 VisitFlow::DESCEND
413 }
414}
415
416impl<Left, Right> VisitableMut for Either<Left, Right>
417where
418 Left: VisitableMut,
419 Right: VisitableMut,
420{
421 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
422 match self {
423 Self::Left(t) => t.accept_mut(v),
424 Self::Right(t) => t.accept_mut(v),
425 }
426 }
427}
428
429impl<Left, Right> Visitable for Either<Left, Right>
430where
431 Left: Visitable,
432 Right: Visitable,
433{
434 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
435 match self {
436 Self::Left(t) => t.accept(v),
437 Self::Right(t) => t.accept(v),
438 }
439 }
440}
441
442impl<'a, T> VisitableMut for Declaration<'a, T, CssMetadata>
443where
444 T: VisitableMut + DeclarationValue<'a, CssMetadata>,
445{
446 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
447 v.visit_declaration(self);
448 self.value.accept_mut(v);
449 v.exit_declaration(self);
450 }
451}
452
453impl<'a, T> QueryableNode for Declaration<'a, T, CssMetadata>
454where
455 T: DeclarationValue<'a, CssMetadata> + QueryableNode,
456{
457 const NODE_ID: NodeId = NodeId::StyleValue;
458
459 fn get_property(&self, kind: PropertyKind) -> Option<Cursor> {
460 match kind {
461 PropertyKind::Name => Some(self.name.into()),
462 _ => None,
463 }
464 }
465
466 fn visit_node(&self) -> VisitNode<'_> {
467 VisitNode::new(self.to_span(), T::NODE_ID, self)
469 }
470}
471
472impl<'a, T> Visitable for Declaration<'a, T, CssMetadata>
473where
474 T: Visitable + DeclarationValue<'a, CssMetadata> + QueryableNode,
475{
476 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
477 let node = self.visit_node();
478 if let visit_flow::VisitAction::SkipChildren = try_visit!(v.consider_node(node)) {
479 return VisitFlow::DESCEND;
480 }
481 if let visit_flow::VisitAction::Descend = visit_flow::try_visit!(v.enter_node(node)) {
482 if let visit_flow::VisitAction::Descend = visit_flow::try_visit!(v.enter_declaration::<T>(self, node)) {
483 try_visit!(self.value.accept(v));
484 }
485 try_visit!(v.exit_declaration::<T>(self, node));
486 }
487 try_visit!(v.exit_node(node));
488 VisitFlow::DESCEND
489 }
490}
491
492impl<'a, T> VisitableMut for DeclarationList<'a, T, CssMetadata>
493where
494 T: VisitableMut + DeclarationValue<'a, CssMetadata>,
495{
496 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
497 for declaration in &mut self.declarations {
498 declaration.accept_mut(v);
499 }
500 }
501}
502
503impl<'a, T> Visitable for DeclarationList<'a, T, CssMetadata>
504where
505 T: Visitable + DeclarationValue<'a, CssMetadata> + QueryableNode,
506{
507 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
508 for declaration in &self.declarations {
509 try_visit!(declaration.accept(v));
510 }
511 VisitFlow::DESCEND
512 }
513}
514
515impl<'a, T, M> VisitableMut for RuleList<'a, T, M>
516where
517 T: VisitableMut + Parse<'a> + ToCursors + ToSpan + NodeWithMetadata<M>,
518 M: NodeMetadata,
519{
520 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
521 self.rules.accept_mut(v);
522 }
523}
524
525impl<'a, T, M> Visitable for RuleList<'a, T, M>
526where
527 T: Visitable + Parse<'a> + ToCursors + ToSpan + NodeWithMetadata<M>,
528 M: NodeMetadata,
529{
530 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
531 self.rules.accept(v)
532 }
533}
534
535impl<'a, P, D, R> VisitableMut for QualifiedRule<'a, P, D, R, CssMetadata>
536where
537 P: VisitableMut + Peek<'a> + Parse<'a> + ToCursors + ToSpan,
538 D: VisitableMut + DeclarationValue<'a, CssMetadata>,
539 R: VisitableMut + Parse<'a> + ToCursors + ToSpan,
540 Block<'a, D, R, CssMetadata>: Parse<'a> + ToCursors + ToSpan,
541{
542 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
543 self.prelude.accept_mut(v);
544 self.block.accept_mut(v);
545 }
546}
547
548impl<'a, P, D, R> Visitable for QualifiedRule<'a, P, D, R, CssMetadata>
549where
550 P: Visitable + Peek<'a> + Parse<'a> + ToCursors + ToSpan,
551 D: Visitable + DeclarationValue<'a, CssMetadata> + QueryableNode,
552 R: Visitable + Parse<'a> + ToCursors + ToSpan,
553 Block<'a, D, R, CssMetadata>: Parse<'a> + ToCursors + ToSpan,
554{
555 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
556 try_visit!(self.prelude.accept(v));
557 self.block.accept(v)
558 }
559}
560
561impl<'a, D, R> VisitableMut for Block<'a, D, R, CssMetadata>
562where
563 D: VisitableMut + DeclarationValue<'a, CssMetadata>,
564 R: VisitableMut + Parse<'a> + ToCursors + ToSpan,
565{
566 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
567 for declaration in &mut self.declarations {
568 declaration.accept_mut(v);
569 }
570 for rule in &mut self.rules {
571 rule.accept_mut(v);
572 }
573 }
574}
575
576impl<'a, D, R> Visitable for Block<'a, D, R, CssMetadata>
577where
578 D: Visitable + DeclarationValue<'a, CssMetadata> + QueryableNode,
579 R: Visitable + Parse<'a> + ToCursors + ToSpan,
580{
581 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
582 for declaration in &self.declarations {
583 try_visit!(declaration.accept(v));
584 }
585 for rule in &self.rules {
586 try_visit!(rule.accept(v));
587 }
588 VisitFlow::DESCEND
589 }
590}
591
592impl<'a, T> VisitableMut for Vec<'a, T>
593where
594 T: VisitableMut,
595{
596 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
597 for node in self {
598 node.accept_mut(v);
599 }
600 }
601}
602
603impl<'a, T> Visitable for Vec<'a, T>
604where
605 T: Visitable,
606{
607 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
608 for node in self {
609 try_visit!(node.accept(v));
610 }
611 VisitFlow::DESCEND
612 }
613}
614
615impl<'a> VisitableMut for BadDeclaration<'a> {
616 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
617 v.visit_bad_declaration(self);
618 v.exit_bad_declaration(self);
619 }
620}
621
622impl<'a> Visitable for BadDeclaration<'a> {
623 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
624 try_visit!(v.visit_bad_declaration(self));
625 try_visit!(v.exit_bad_declaration(self));
626 VisitFlow::DESCEND
627 }
628}
629
630impl<'a> VisitableMut for ComponentValues<'a> {
631 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
632 v.visit_component_values(self);
633 for value in &mut self.values {
634 value.accept_mut(v);
635 }
636 v.exit_component_values(self);
637 }
638}
639
640impl<'a> QueryableNode for ComponentValues<'a> {
641 const NODE_ID: NodeId = NodeId::ComponentValues;
642}
643
644impl<'a> Visitable for ComponentValues<'a> {
645 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
646 let node = QueryableNode::visit_node(self);
647 if let VisitAction::SkipChildren = try_visit!(v.consider_node(node)) {
648 return VisitFlow::DESCEND;
649 }
650 if let VisitAction::Descend = try_visit!(v.enter_node(node)) {
651 if let VisitAction::Descend = try_visit!(v.visit_component_values(self)) {
652 for value in &self.values {
653 try_visit!(value.accept(v));
654 }
655 }
656 try_visit!(v.exit_component_values(self));
657 }
658 try_visit!(v.exit_node(node));
659 VisitFlow::DESCEND
660 }
661}
662
663impl<'a> VisitableMut for ComponentValue<'a> {
664 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
665 v.visit_component_value(self);
666 match self {
667 ComponentValue::SimpleBlock(block) => block.values.accept_mut(v),
668 ComponentValue::Function(function) => function.params.accept_mut(v),
669 _ => {}
670 }
671 v.exit_component_value(self);
672 }
673}
674
675impl<'a> QueryableNode for ComponentValue<'a> {
676 const NODE_ID: NodeId = NodeId::ComponentValue;
677}
678
679impl<'a> Visitable for ComponentValue<'a> {
680 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
681 let node = QueryableNode::visit_node(self);
682 if let VisitAction::SkipChildren = try_visit!(v.consider_node(node)) {
683 return VisitFlow::DESCEND;
684 }
685 if let VisitAction::Descend = try_visit!(v.enter_node(node)) {
686 if let VisitAction::Descend = try_visit!(v.visit_component_value(self)) {
687 match self {
688 ComponentValue::SimpleBlock(block) => {
689 try_visit!(block.values.accept(v));
690 }
691 ComponentValue::Function(function) => {
692 try_visit!(function.params.accept(v));
693 }
694 _ => {}
695 }
696 }
697 try_visit!(v.exit_component_value(self));
698 }
699 try_visit!(v.exit_node(node));
700 VisitFlow::DESCEND
701 }
702}
703
704impl<'a> VisitableMut for Unresolved<'a> {
705 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
706}
707
708impl<'a> Visitable for Unresolved<'a> {
709 fn accept<V: Visit>(&self, _: &mut V) -> VisitFlow {
710 VisitFlow::DESCEND
711 }
712}
713
714impl<D, M> VisitableMut for NoBlockAllowed<D, M> {
715 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
716}
717
718impl<D, M> Visitable for NoBlockAllowed<D, M> {
719 fn accept<V: Visit>(&self, _: &mut V) -> VisitFlow {
720 VisitFlow::DESCEND
721 }
722}
723
724impl<'a, D> VisitableMut for DeclarationGroup<'a, D, CssMetadata>
725where
726 D: VisitableMut + DeclarationValue<'a, CssMetadata>,
727{
728 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
729 for declaration in &mut self.declarations {
730 declaration.accept_mut(v)
731 }
732 }
733}
734
735impl<'a, D> Visitable for DeclarationGroup<'a, D, CssMetadata>
736where
737 D: Visitable + DeclarationValue<'a, CssMetadata> + QueryableNode,
738{
739 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
740 for declaration in &self.declarations {
741 try_visit!(declaration.accept(v));
742 }
743 VisitFlow::DESCEND
744 }
745}
746
747impl<'a, D> VisitableMut for DeclarationOrBad<'a, D, CssMetadata>
748where
749 D: VisitableMut + DeclarationValue<'a, CssMetadata>,
750{
751 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
752 match self {
753 Self::Declaration(d) => d.accept_mut(v),
754 Self::Bad(b) => b.accept_mut(v),
755 }
756 }
757}
758
759impl<'a, D> Visitable for DeclarationOrBad<'a, D, CssMetadata>
760where
761 D: Visitable + DeclarationValue<'a, CssMetadata> + QueryableNode,
762{
763 fn accept<V: Visit>(&self, v: &mut V) -> VisitFlow {
764 match self {
765 Self::Declaration(d) => d.accept(v),
766 Self::Bad(b) => b.accept(v),
767 }
768 }
769}
770
771macro_rules! impl_tuple_mut {
772 ($($T:ident),*) => {
773 impl<$($T),*> VisitableMut for ($($T),*)
774 where
775 $($T: VisitableMut,)*
776 {
777 #[allow(non_snake_case)]
778 #[allow(unused)]
779 fn accept_mut<VI: VisitMut>(&mut self, v: &mut VI) {
780 let ($($T),*) = self;
781 $($T.accept_mut(v);)*
782 }
783 }
784 };
785}
786
787impl_tuple_mut!(T, U);
788impl_tuple_mut!(T, U, V);
789impl_tuple_mut!(T, U, V, W);
790impl_tuple_mut!(T, U, V, W, X);
791impl_tuple_mut!(T, U, V, W, X, Y);
792impl_tuple_mut!(T, U, V, W, X, Y, Z);
793impl_tuple_mut!(T, U, V, W, X, Y, Z, A);
794impl_tuple_mut!(T, U, V, W, X, Y, Z, A, B);
795impl_tuple_mut!(T, U, V, W, X, Y, Z, A, B, C);
796impl_tuple_mut!(T, U, V, W, X, Y, Z, A, B, C, D);
797impl_tuple_mut!(T, U, V, W, X, Y, Z, A, B, C, D, E);
798
799macro_rules! impl_tuple {
800 ($($T:ident),*) => {
801 impl<$($T),*> Visitable for ($($T),*)
802 where
803 $($T: Visitable,)*
804 {
805 #[allow(non_snake_case)]
806 #[allow(unused)]
807 fn accept<VI: Visit>(&self, v: &mut VI) -> VisitFlow {
808 let ($($T),*) = self;
809 $(try_visit!($T.accept(v));)*
810 VisitFlow::DESCEND
811 }
812 }
813 };
814}
815impl_tuple!(T, U);
816impl_tuple!(T, U, V);
817impl_tuple!(T, U, V, W);
818impl_tuple!(T, U, V, W, X);
819impl_tuple!(T, U, V, W, X, Y);
820impl_tuple!(T, U, V, W, X, Y, Z);
821impl_tuple!(T, U, V, W, X, Y, Z, A);
822impl_tuple!(T, U, V, W, X, Y, Z, A, B);
823impl_tuple!(T, U, V, W, X, Y, Z, A, B, C);
824impl_tuple!(T, U, V, W, X, Y, Z, A, B, C, D);
825impl_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E);