swc_css_ast/
at_rule.rs

1use is_macro::Is;
2use string_enum::StringEnum;
3use swc_atoms::Atom;
4use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span};
5
6use crate::{
7    CustomIdent, CustomPropertyName, DashedIdent, Declaration, Dimension, FamilyName,
8    ForgivingSelectorList, Function, Ident, ListOfComponentValues, Number, Percentage, Ratio,
9    SelectorList, SimpleBlock, Str, Url,
10};
11
12#[ast_node("AtRule")]
13#[derive(Eq, Hash, EqIgnoreSpan)]
14pub struct AtRule {
15    pub span: Span,
16    pub name: AtRuleName,
17    #[cfg_attr(
18        feature = "encoding-impl",
19        encoding(with = "cbor4ii::core::types::Maybe")
20    )]
21    pub prelude: Option<Box<AtRulePrelude>>,
22    #[cfg_attr(
23        feature = "encoding-impl",
24        encoding(with = "cbor4ii::core::types::Maybe")
25    )]
26    pub block: Option<SimpleBlock>,
27}
28
29#[ast_node(no_unknown)]
30#[derive(Eq, Hash, Is, EqIgnoreSpan)]
31pub enum AtRuleName {
32    #[tag("DashedIdent")]
33    DashedIdent(DashedIdent),
34
35    #[tag("Ident")]
36    Ident(Ident),
37}
38
39impl PartialEq<str> for AtRuleName {
40    fn eq(&self, other: &str) -> bool {
41        match self {
42            AtRuleName::DashedIdent(v) => *v == *other,
43            AtRuleName::Ident(v) => *v == *other,
44        }
45    }
46}
47
48impl PartialEq<Atom> for AtRuleName {
49    fn eq(&self, other: &Atom) -> bool {
50        match self {
51            AtRuleName::DashedIdent(v) => v.value == *other,
52            AtRuleName::Ident(v) => v.value == *other,
53        }
54    }
55}
56
57#[ast_node(no_unknown)]
58#[derive(Eq, Hash, Is, EqIgnoreSpan)]
59pub enum AtRulePrelude {
60    #[tag("ListOfComponentValues")]
61    ListOfComponentValues(ListOfComponentValues),
62    #[tag("Str")]
63    CharsetPrelude(Str),
64    #[tag("CustomPropertyName")]
65    PropertyPrelude(CustomPropertyName),
66    #[tag("CustomIdent")]
67    CounterStylePrelude(CustomIdent),
68    #[tag("ColorProfileName")]
69    ColorProfilePrelude(ColorProfileName),
70    #[tag("DocumentPrelude")]
71    DocumentPrelude(DocumentPrelude),
72    #[tag("DashedIdent")]
73    FontPaletteValuesPrelude(DashedIdent),
74    #[tag("FontFeatureValuesPrelude")]
75    FontFeatureValuesPrelude(FontFeatureValuesPrelude),
76    #[tag("SelectorList")]
77    NestPrelude(SelectorList),
78    #[tag("KeyframesName")]
79    KeyframesPrelude(KeyframesName),
80    #[tag("ImportPrelude")]
81    ImportPrelude(ImportPrelude),
82    #[tag("NamespacePrelude")]
83    NamespacePrelude(NamespacePrelude),
84    #[tag("MediaQueryList")]
85    MediaPrelude(MediaQueryList),
86    #[tag("SupportsCondition")]
87    SupportsPrelude(SupportsCondition),
88    #[tag("PageSelectorList")]
89    PagePrelude(PageSelectorList),
90    #[tag("LayerPrelude")]
91    LayerPrelude(LayerPrelude),
92    #[tag("ContainerCondition")]
93    ContainerPrelude(ContainerCondition),
94    #[tag("CustomMedia")]
95    CustomMediaPrelude(CustomMediaQuery),
96    #[tag("ScopeRange")]
97    ScopePrelude(ScopeRange),
98}
99
100#[ast_node("ScopeRange")]
101#[derive(Eq, Hash, EqIgnoreSpan)]
102pub struct ScopeRange {
103    pub span: Span,
104    /// https://drafts.csswg.org/css-cascade-6/#typedef-scope-start
105    #[cfg_attr(
106        feature = "encoding-impl",
107        encoding(with = "cbor4ii::core::types::Maybe")
108    )]
109    pub scope_start: Option<ForgivingSelectorList>,
110    /// https://drafts.csswg.org/css-cascade-6/#typedef-scope-end
111    #[cfg_attr(
112        feature = "encoding-impl",
113        encoding(with = "cbor4ii::core::types::Maybe")
114    )]
115    pub scope_end: Option<ForgivingSelectorList>,
116}
117
118#[ast_node(no_unknown)]
119#[derive(Eq, Hash, Is, EqIgnoreSpan)]
120pub enum ColorProfileName {
121    #[tag("DashedIdent")]
122    DashedIdent(DashedIdent),
123    #[tag("Ident")]
124    Ident(Ident),
125}
126
127#[ast_node("DocumentPrelude")]
128#[derive(Eq, Hash, EqIgnoreSpan)]
129pub struct DocumentPrelude {
130    pub span: Span,
131    pub matching_functions: Vec<DocumentPreludeMatchingFunction>,
132}
133
134#[ast_node("FontFeatureValuesPrelude")]
135#[derive(Eq, Hash, EqIgnoreSpan)]
136pub struct FontFeatureValuesPrelude {
137    pub span: Span,
138    pub font_family: Vec<FamilyName>,
139}
140
141#[ast_node(no_unknown)]
142#[derive(Eq, Hash, Is, EqIgnoreSpan)]
143pub enum DocumentPreludeMatchingFunction {
144    #[tag("Url")]
145    Url(Url),
146    #[tag("Function")]
147    Function(Function),
148}
149
150#[ast_node(no_unknown)]
151#[derive(Eq, Hash, Is, EqIgnoreSpan)]
152pub enum KeyframesName {
153    #[tag("CustomIdent")]
154    CustomIdent(Box<CustomIdent>),
155    #[tag("Str")]
156    Str(Box<Str>),
157    /// Only for CSS modules
158    #[tag("KeyframesPseudoPrefix")]
159    PseudoPrefix(Box<KeyframesPseudoPrefix>),
160    /// Only for CSS modules
161    #[tag("KeyframesPseudoFunction")]
162    PseudoFunction(Box<KeyframesPseudoFunction>),
163}
164
165#[ast_node("KeyframesPseudo")]
166#[derive(Eq, Hash, EqIgnoreSpan)]
167pub struct KeyframesPseudoPrefix {
168    pub span: Span,
169    pub pseudo: Ident,
170    pub name: KeyframesName,
171}
172
173#[ast_node("KeyframesPseudo")]
174#[derive(Eq, Hash, EqIgnoreSpan)]
175pub struct KeyframesPseudoFunction {
176    pub span: Span,
177    pub pseudo: Ident,
178    pub name: KeyframesName,
179}
180
181#[ast_node("KeyframeBlock")]
182#[derive(Eq, Hash, EqIgnoreSpan)]
183pub struct KeyframeBlock {
184    pub span: Span,
185    pub prelude: Vec<KeyframeSelector>,
186    pub block: SimpleBlock,
187}
188
189#[ast_node(no_unknown)]
190#[derive(Eq, Hash, Is, EqIgnoreSpan)]
191pub enum KeyframeSelector {
192    #[tag("Ident")]
193    Ident(Ident),
194    #[tag("Percentage")]
195    Percentage(Percentage),
196}
197
198#[ast_node("ImportPrelude")]
199#[derive(Eq, Hash, EqIgnoreSpan)]
200pub struct ImportPrelude {
201    pub span: Span,
202    pub href: Box<ImportHref>,
203    #[cfg_attr(
204        feature = "encoding-impl",
205        encoding(with = "cbor4ii::core::types::Maybe")
206    )]
207    pub layer_name: Option<Box<ImportLayerName>>,
208    #[cfg_attr(
209        feature = "encoding-impl",
210        encoding(with = "cbor4ii::core::types::Maybe")
211    )]
212    pub import_conditions: Option<Box<ImportConditions>>,
213}
214
215#[ast_node(no_unknown)]
216#[derive(Eq, Hash, Is, EqIgnoreSpan)]
217pub enum ImportHref {
218    #[tag("Url")]
219    Url(Url),
220    #[tag("Str")]
221    Str(Str),
222}
223
224#[ast_node(no_unknown)]
225#[derive(Eq, Hash, Is, EqIgnoreSpan)]
226pub enum ImportLayerName {
227    #[tag("Ident")]
228    Ident(Ident),
229    #[tag("Function")]
230    Function(Function),
231}
232
233#[ast_node("ImportCondition")]
234#[derive(Eq, Hash, EqIgnoreSpan)]
235pub struct ImportConditions {
236    pub span: Span,
237    #[cfg_attr(
238        feature = "encoding-impl",
239        encoding(with = "cbor4ii::core::types::Maybe")
240    )]
241    pub supports: Option<Box<Function>>,
242    #[cfg_attr(
243        feature = "encoding-impl",
244        encoding(with = "cbor4ii::core::types::Maybe")
245    )]
246    pub media: Option<Box<MediaQueryList>>,
247}
248
249#[ast_node("NamespacePrelude")]
250#[derive(Eq, Hash, EqIgnoreSpan)]
251pub struct NamespacePrelude {
252    pub span: Span,
253    #[cfg_attr(
254        feature = "encoding-impl",
255        encoding(with = "cbor4ii::core::types::Maybe")
256    )]
257    pub prefix: Option<Ident>,
258    pub uri: Box<NamespacePreludeUri>,
259}
260
261#[ast_node(no_unknown)]
262#[derive(Eq, Hash, Is, EqIgnoreSpan)]
263pub enum NamespacePreludeUri {
264    #[tag("Url")]
265    Url(Url),
266    #[tag("Str")]
267    Str(Str),
268}
269
270#[ast_node("MediaQueryList")]
271#[derive(Eq, Hash, EqIgnoreSpan)]
272pub struct MediaQueryList {
273    pub span: Span,
274    pub queries: Vec<MediaQuery>,
275}
276
277#[ast_node("MediaQuery")]
278#[derive(Eq, Hash)]
279pub struct MediaQuery {
280    pub span: Span,
281    #[cfg_attr(
282        feature = "encoding-impl",
283        encoding(with = "cbor4ii::core::types::Maybe")
284    )]
285    pub modifier: Option<Ident>,
286    #[cfg_attr(
287        feature = "encoding-impl",
288        encoding(with = "cbor4ii::core::types::Maybe")
289    )]
290    pub media_type: Option<MediaType>,
291    #[cfg_attr(
292        feature = "encoding-impl",
293        encoding(with = "cbor4ii::core::types::Maybe")
294    )]
295    pub keyword: Option<Ident>,
296    #[cfg_attr(
297        feature = "encoding-impl",
298        encoding(with = "cbor4ii::core::types::Maybe")
299    )]
300    pub condition: Option<Box<MediaConditionType>>,
301}
302
303impl Take for MediaQuery {
304    #[inline]
305    fn dummy() -> Self {
306        Self {
307            span: Take::dummy(),
308            modifier: Take::dummy(),
309            media_type: Take::dummy(),
310            keyword: Take::dummy(),
311            condition: Take::dummy(),
312        }
313    }
314}
315
316impl EqIgnoreSpan for MediaQuery {
317    fn eq_ignore_span(&self, other: &Self) -> bool {
318        self.modifier.eq_ignore_span(&other.modifier)
319            && self.media_type.eq_ignore_span(&other.media_type)
320            && self.condition.eq_ignore_span(&other.condition)
321    }
322}
323
324#[ast_node(no_unknown)]
325#[derive(Eq, Hash, Is, EqIgnoreSpan)]
326pub enum MediaType {
327    #[tag("Ident")]
328    Ident(Ident),
329}
330
331#[ast_node(no_unknown)]
332#[derive(Eq, Hash, Is, EqIgnoreSpan)]
333pub enum MediaConditionType {
334    #[tag("MediaCondition")]
335    All(MediaCondition),
336
337    #[tag("MediaConditionWithoutOr")]
338    WithoutOr(MediaConditionWithoutOr),
339}
340
341#[ast_node("MediaCondition")]
342#[derive(Eq, Hash, EqIgnoreSpan)]
343pub struct MediaCondition {
344    pub span: Span,
345    pub conditions: Vec<MediaConditionAllType>,
346}
347
348#[ast_node("MediaConditionWithoutOr")]
349#[derive(Eq, Hash, EqIgnoreSpan)]
350pub struct MediaConditionWithoutOr {
351    pub span: Span,
352    pub conditions: Vec<MediaConditionWithoutOrType>,
353}
354
355#[ast_node(no_unknown)]
356#[derive(Eq, Hash, Is, EqIgnoreSpan)]
357pub enum MediaConditionAllType {
358    #[tag("MediaNot")]
359    Not(MediaNot),
360
361    #[tag("MediaAnd")]
362    And(MediaAnd),
363
364    #[tag("MediaOr")]
365    Or(MediaOr),
366
367    #[tag("MediaInParens")]
368    MediaInParens(MediaInParens),
369}
370
371#[ast_node(no_unknown)]
372#[derive(Eq, Hash, Is, EqIgnoreSpan)]
373pub enum MediaConditionWithoutOrType {
374    #[tag("MediaNot")]
375    Not(MediaNot),
376
377    #[tag("MediaAnd")]
378    And(MediaAnd),
379
380    #[tag("MediaInParens")]
381    MediaInParens(MediaInParens),
382}
383
384#[ast_node("MediaNot")]
385#[derive(Eq, Hash)]
386pub struct MediaNot {
387    pub span: Span,
388    #[cfg_attr(
389        feature = "encoding-impl",
390        encoding(with = "cbor4ii::core::types::Maybe")
391    )]
392    pub keyword: Option<Ident>,
393    pub condition: MediaInParens,
394}
395
396impl EqIgnoreSpan for MediaNot {
397    fn eq_ignore_span(&self, other: &Self) -> bool {
398        self.condition.eq_ignore_span(&other.condition)
399    }
400}
401
402#[ast_node("MediaAnd")]
403#[derive(Eq, Hash)]
404pub struct MediaAnd {
405    pub span: Span,
406    #[cfg_attr(
407        feature = "encoding-impl",
408        encoding(with = "cbor4ii::core::types::Maybe")
409    )]
410    pub keyword: Option<Ident>,
411    pub condition: MediaInParens,
412}
413
414impl EqIgnoreSpan for MediaAnd {
415    fn eq_ignore_span(&self, other: &Self) -> bool {
416        self.condition.eq_ignore_span(&other.condition)
417    }
418}
419
420#[ast_node("MediaOr")]
421#[derive(Eq, Hash)]
422pub struct MediaOr {
423    pub span: Span,
424    #[cfg_attr(
425        feature = "encoding-impl",
426        encoding(with = "cbor4ii::core::types::Maybe")
427    )]
428    pub keyword: Option<Ident>,
429    pub condition: MediaInParens,
430}
431
432impl EqIgnoreSpan for MediaOr {
433    fn eq_ignore_span(&self, other: &Self) -> bool {
434        self.condition.eq_ignore_span(&other.condition)
435    }
436}
437
438#[ast_node(no_unknown)]
439#[derive(Eq, Hash, Is, EqIgnoreSpan)]
440pub enum MediaInParens {
441    #[tag("MediaCondition")]
442    MediaCondition(MediaCondition),
443
444    #[tag("MediaFeature")]
445    Feature(Box<MediaFeature>),
446
447    #[tag("GeneralEnclosed")]
448    GeneralEnclosed(GeneralEnclosed),
449}
450
451#[ast_node(no_unknown)]
452#[derive(Eq, Hash, Is, EqIgnoreSpan)]
453pub enum MediaFeature {
454    #[tag("MediaFeaturePlain")]
455    Plain(MediaFeaturePlain),
456
457    #[tag("MediaFeatureBoolean")]
458    Boolean(MediaFeatureBoolean),
459
460    #[tag("MediaFeatureRange")]
461    Range(MediaFeatureRange),
462
463    #[tag("MediaFeatureRangeInterval")]
464    RangeInterval(MediaFeatureRangeInterval),
465}
466
467#[ast_node(no_unknown)]
468#[derive(Eq, Hash, Is, EqIgnoreSpan)]
469pub enum MediaFeatureName {
470    #[tag("Ident")]
471    Ident(Ident),
472
473    #[tag("ExtensionName")]
474    ExtensionName(ExtensionName),
475}
476
477#[ast_node(no_unknown)]
478#[derive(Eq, Hash, Is, EqIgnoreSpan)]
479pub enum MediaFeatureValue {
480    #[tag("Number")]
481    Number(Number),
482
483    #[tag("Dimension")]
484    Dimension(Dimension),
485
486    #[tag("Ident")]
487    Ident(Ident),
488
489    #[tag("Ratio")]
490    Ratio(Ratio),
491
492    #[tag("Function")]
493    Function(Function),
494}
495
496#[ast_node("MediaFeaturePlain")]
497#[derive(Eq, Hash, EqIgnoreSpan)]
498pub struct MediaFeaturePlain {
499    pub span: Span,
500    pub name: MediaFeatureName,
501    pub value: Box<MediaFeatureValue>,
502}
503
504#[ast_node("MediaFeatureBoolean")]
505#[derive(Eq, Hash, EqIgnoreSpan)]
506pub struct MediaFeatureBoolean {
507    pub span: Span,
508    pub name: MediaFeatureName,
509}
510
511#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, Is, EqIgnoreSpan)]
512#[cfg_attr(
513    feature = "rkyv",
514    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
515)]
516#[cfg_attr(feature = "rkyv", derive(bytecheck::CheckBytes))]
517#[cfg_attr(feature = "rkyv", repr(u32))]
518#[cfg_attr(
519    feature = "encoding-impl",
520    derive(::swc_common::Encode, ::swc_common::Decode)
521)]
522//#[cfg_attr(
523//    feature = "rkyv",
524//    archive(bound(serialize = "__S: rkyv::ser::ScratchSpace +
525// rkyv::ser::Serializer"))
526//)]
527pub enum MediaFeatureRangeComparison {
528    /// `<`
529    Lt,
530
531    /// `<=`
532    Le,
533
534    /// `>`
535    Gt,
536
537    /// `>=`
538    Ge,
539
540    /// `=`
541    Eq,
542}
543
544#[ast_node("MediaFeatureRange")]
545#[derive(Eq, Hash, EqIgnoreSpan)]
546pub struct MediaFeatureRange {
547    pub span: Span,
548    pub left: Box<MediaFeatureValue>,
549    pub comparison: MediaFeatureRangeComparison,
550    pub right: Box<MediaFeatureValue>,
551}
552
553#[ast_node("MediaFeatureRangeInterval")]
554#[derive(Eq, Hash, EqIgnoreSpan)]
555pub struct MediaFeatureRangeInterval {
556    pub span: Span,
557    pub left: Box<MediaFeatureValue>,
558    #[cfg_attr(feature = "serde-impl", serde(rename = "leftComparison"))]
559    pub left_comparison: MediaFeatureRangeComparison,
560    pub name: MediaFeatureName,
561    #[cfg_attr(feature = "serde-impl", serde(rename = "rightComparison"))]
562    pub right_comparison: MediaFeatureRangeComparison,
563    pub right: Box<MediaFeatureValue>,
564}
565
566#[ast_node("SupportsCondition")]
567#[derive(Eq, Hash, EqIgnoreSpan)]
568pub struct SupportsCondition {
569    pub span: Span,
570    pub conditions: Vec<SupportsConditionType>,
571}
572
573#[ast_node(no_unknown)]
574#[derive(Eq, Hash, Is, EqIgnoreSpan)]
575pub enum SupportsConditionType {
576    #[tag("SupportsNot")]
577    Not(SupportsNot),
578
579    #[tag("SupportsAnd")]
580    And(SupportsAnd),
581
582    #[tag("SupportsOr")]
583    Or(SupportsOr),
584
585    #[tag("SupportsInParens")]
586    SupportsInParens(SupportsInParens),
587}
588
589#[ast_node("SupportsNot")]
590#[derive(Eq, Hash)]
591pub struct SupportsNot {
592    pub span: Span,
593    #[cfg_attr(
594        feature = "encoding-impl",
595        encoding(with = "cbor4ii::core::types::Maybe")
596    )]
597    pub keyword: Option<Ident>,
598    pub condition: Box<SupportsInParens>,
599}
600
601impl EqIgnoreSpan for SupportsNot {
602    fn eq_ignore_span(&self, other: &Self) -> bool {
603        self.condition.eq_ignore_span(&other.condition)
604    }
605}
606
607#[ast_node("SupportsAnd")]
608#[derive(Eq, Hash)]
609pub struct SupportsAnd {
610    pub span: Span,
611    #[cfg_attr(
612        feature = "encoding-impl",
613        encoding(with = "cbor4ii::core::types::Maybe")
614    )]
615    pub keyword: Option<Ident>,
616    pub condition: Box<SupportsInParens>,
617}
618
619impl EqIgnoreSpan for SupportsAnd {
620    fn eq_ignore_span(&self, other: &Self) -> bool {
621        self.condition.eq_ignore_span(&other.condition)
622    }
623}
624
625#[ast_node("SupportsOr")]
626#[derive(Eq, Hash)]
627pub struct SupportsOr {
628    pub span: Span,
629    #[cfg_attr(
630        feature = "encoding-impl",
631        encoding(with = "cbor4ii::core::types::Maybe")
632    )]
633    pub keyword: Option<Ident>,
634    pub condition: Box<SupportsInParens>,
635}
636
637impl EqIgnoreSpan for SupportsOr {
638    fn eq_ignore_span(&self, other: &Self) -> bool {
639        self.condition.eq_ignore_span(&other.condition)
640    }
641}
642
643#[ast_node(no_unknown)]
644#[derive(Eq, Hash, Is, EqIgnoreSpan)]
645pub enum SupportsInParens {
646    #[tag("SupportsCondition")]
647    SupportsCondition(SupportsCondition),
648
649    #[tag("SupportsFeature")]
650    Feature(SupportsFeature),
651
652    #[tag("GeneralEnclosed")]
653    GeneralEnclosed(GeneralEnclosed),
654}
655
656#[ast_node(no_unknown)]
657#[derive(Eq, Hash, Is, EqIgnoreSpan)]
658pub enum SupportsFeature {
659    #[tag("Declaration")]
660    Declaration(Box<Declaration>),
661    #[tag("Function")]
662    Function(Function),
663}
664
665#[ast_node(no_unknown)]
666#[derive(Eq, Hash, Is, EqIgnoreSpan)]
667pub enum GeneralEnclosed {
668    #[tag("Function")]
669    Function(Function),
670    #[tag("SimpleBlock")]
671    SimpleBlock(SimpleBlock),
672}
673
674#[ast_node("PageSelectorList")]
675#[derive(Eq, Hash, EqIgnoreSpan)]
676pub struct PageSelectorList {
677    pub span: Span,
678    pub selectors: Vec<PageSelector>,
679}
680
681#[ast_node("PageSelector")]
682#[derive(Eq, Hash, EqIgnoreSpan)]
683pub struct PageSelector {
684    pub span: Span,
685    #[cfg_attr(
686        feature = "encoding-impl",
687        encoding(with = "cbor4ii::core::types::Maybe")
688    )]
689    pub page_type: Option<PageSelectorType>,
690    #[cfg_attr(
691        feature = "encoding-impl",
692        encoding(with = "cbor4ii::core::types::Maybe")
693    )]
694    pub pseudos: Option<Vec<PageSelectorPseudo>>,
695}
696
697#[ast_node("PageSelectorType")]
698#[derive(Eq, Hash, EqIgnoreSpan)]
699pub struct PageSelectorType {
700    pub span: Span,
701    pub value: Ident,
702}
703
704#[ast_node("PageSelectorPseudo")]
705#[derive(Eq, Hash, EqIgnoreSpan)]
706pub struct PageSelectorPseudo {
707    pub span: Span,
708    pub value: Ident,
709}
710
711#[ast_node(no_unknown)]
712#[derive(Eq, Hash, Is, EqIgnoreSpan)]
713pub enum LayerPrelude {
714    #[tag("LayerName")]
715    Name(LayerName),
716    #[tag("LayerNameList")]
717    NameList(LayerNameList),
718}
719
720#[ast_node("LayerName")]
721#[derive(Eq, Hash, EqIgnoreSpan)]
722pub struct LayerName {
723    pub span: Span,
724    pub name: Vec<Ident>,
725}
726
727#[ast_node("LayerNameList")]
728#[derive(Eq, Hash, EqIgnoreSpan)]
729pub struct LayerNameList {
730    pub span: Span,
731    pub name_list: Vec<LayerName>,
732}
733
734#[ast_node("ContainerCondition")]
735#[derive(Eq, Hash, EqIgnoreSpan)]
736pub struct ContainerCondition {
737    pub span: Span,
738    #[cfg_attr(
739        feature = "encoding-impl",
740        encoding(with = "cbor4ii::core::types::Maybe")
741    )]
742    pub name: Option<ContainerName>,
743    pub query: ContainerQuery,
744}
745
746#[ast_node(no_unknown)]
747#[derive(Eq, Hash, Is, EqIgnoreSpan)]
748pub enum ContainerName {
749    #[tag("CustomIdent")]
750    CustomIdent(CustomIdent),
751}
752
753#[ast_node("ContainerQuery")]
754#[derive(Eq, Hash, EqIgnoreSpan)]
755pub struct ContainerQuery {
756    pub span: Span,
757    pub queries: Vec<ContainerQueryType>,
758}
759
760#[ast_node(no_unknown)]
761#[derive(Eq, Hash, Is, EqIgnoreSpan)]
762pub enum ContainerQueryType {
763    #[tag("ContainerQueryNot")]
764    Not(ContainerQueryNot),
765
766    #[tag("ContainerQueryAnd")]
767    And(ContainerQueryAnd),
768
769    #[tag("ContainerQueryOr")]
770    Or(ContainerQueryOr),
771
772    #[tag("QueryInParens")]
773    QueryInParens(QueryInParens),
774}
775
776#[ast_node("ContainerQueryNot")]
777#[derive(Eq, Hash)]
778pub struct ContainerQueryNot {
779    pub span: Span,
780    #[cfg_attr(
781        feature = "encoding-impl",
782        encoding(with = "cbor4ii::core::types::Maybe")
783    )]
784    pub keyword: Option<Ident>,
785    pub query: QueryInParens,
786}
787
788impl EqIgnoreSpan for ContainerQueryNot {
789    fn eq_ignore_span(&self, other: &Self) -> bool {
790        self.query.eq_ignore_span(&other.query)
791    }
792}
793
794#[ast_node("ContainerQueryAnd")]
795#[derive(Eq, Hash)]
796pub struct ContainerQueryAnd {
797    pub span: Span,
798    #[cfg_attr(
799        feature = "encoding-impl",
800        encoding(with = "cbor4ii::core::types::Maybe")
801    )]
802    pub keyword: Option<Ident>,
803    pub query: QueryInParens,
804}
805
806impl EqIgnoreSpan for ContainerQueryAnd {
807    fn eq_ignore_span(&self, other: &Self) -> bool {
808        self.query.eq_ignore_span(&other.query)
809    }
810}
811
812#[ast_node("ContainerQueryOr")]
813#[derive(Eq, Hash)]
814pub struct ContainerQueryOr {
815    pub span: Span,
816    #[cfg_attr(
817        feature = "encoding-impl",
818        encoding(with = "cbor4ii::core::types::Maybe")
819    )]
820    pub keyword: Option<Ident>,
821    pub query: QueryInParens,
822}
823
824impl EqIgnoreSpan for ContainerQueryOr {
825    fn eq_ignore_span(&self, other: &Self) -> bool {
826        self.query.eq_ignore_span(&other.query)
827    }
828}
829
830#[ast_node(no_unknown)]
831#[derive(Eq, Hash, Is, EqIgnoreSpan)]
832pub enum QueryInParens {
833    #[tag("ContainerQuery")]
834    ContainerQuery(Box<ContainerQuery>),
835
836    #[tag("SizeFeature")]
837    SizeFeature(SizeFeature),
838
839    // TODO implement style
840    // https://drafts.csswg.org/css-contain-3/#typedef-style-query
841    // #[tag("Function")]
842    // Function(Function),
843    #[tag("GeneralEnclosed")]
844    GeneralEnclosed(GeneralEnclosed),
845}
846
847#[ast_node(no_unknown)]
848#[derive(Eq, Hash, Is, EqIgnoreSpan)]
849pub enum SizeFeature {
850    #[tag("SizeFeaturePlain")]
851    Plain(SizeFeaturePlain),
852
853    #[tag("SizeFeatureBoolean")]
854    Boolean(SizeFeatureBoolean),
855
856    #[tag("SizeFeatureRange")]
857    Range(SizeFeatureRange),
858
859    #[tag("SizeFeatureRangeInterval")]
860    RangeInterval(SizeFeatureRangeInterval),
861}
862
863#[ast_node("SizeFeaturePlain")]
864#[derive(Eq, Hash, EqIgnoreSpan)]
865pub struct SizeFeaturePlain {
866    pub span: Span,
867    pub name: SizeFeatureName,
868    pub value: Box<SizeFeatureValue>,
869}
870
871#[ast_node("SizeFeatureBoolean")]
872#[derive(Eq, Hash, EqIgnoreSpan)]
873pub struct SizeFeatureBoolean {
874    pub span: Span,
875    pub name: SizeFeatureName,
876}
877
878#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, Is, EqIgnoreSpan)]
879#[cfg_attr(
880    feature = "rkyv",
881    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
882)]
883#[cfg_attr(feature = "rkyv", derive(bytecheck::CheckBytes))]
884#[cfg_attr(feature = "rkyv", repr(u32))]
885//#[cfg_attr(
886//    feature = "rkyv",
887//    archive(bound(serialize = "__S: rkyv::ser::ScratchSpace +
888// rkyv::ser::Serializer"))
889//)]
890#[cfg_attr(
891    feature = "encoding-impl",
892    derive(::swc_common::Encode, ::swc_common::Decode)
893)]
894pub enum SizeFeatureRangeComparison {
895    /// `<`
896    Lt,
897
898    /// `<=`
899    Le,
900
901    /// `>`
902    Gt,
903
904    /// `>=`
905    Ge,
906
907    /// `=`
908    Eq,
909}
910
911#[ast_node("SizeFeatureRange")]
912#[derive(Eq, Hash, EqIgnoreSpan)]
913pub struct SizeFeatureRange {
914    pub span: Span,
915    pub left: Box<SizeFeatureValue>,
916    pub comparison: SizeFeatureRangeComparison,
917    pub right: Box<SizeFeatureValue>,
918}
919
920#[ast_node("SizeFeatureRangeInterval")]
921#[derive(Eq, Hash, EqIgnoreSpan)]
922pub struct SizeFeatureRangeInterval {
923    pub span: Span,
924    pub left: Box<SizeFeatureValue>,
925    #[cfg_attr(feature = "serde-impl", serde(rename = "leftComparison"))]
926    pub left_comparison: SizeFeatureRangeComparison,
927    pub name: SizeFeatureName,
928    #[cfg_attr(feature = "serde-impl", serde(rename = "rightComparison"))]
929    pub right_comparison: SizeFeatureRangeComparison,
930    pub right: Box<SizeFeatureValue>,
931}
932
933#[ast_node(no_unknown)]
934#[derive(Eq, Hash, Is, EqIgnoreSpan)]
935pub enum SizeFeatureValue {
936    #[tag("Number")]
937    Number(Number),
938
939    #[tag("Dimension")]
940    Dimension(Dimension),
941
942    #[tag("Ident")]
943    Ident(Ident),
944
945    #[tag("Ratio")]
946    Ratio(Ratio),
947
948    #[tag("Function")]
949    Function(Function),
950}
951
952#[ast_node(no_unknown)]
953#[derive(Eq, Hash, Is, EqIgnoreSpan)]
954pub enum SizeFeatureName {
955    #[tag("Ident")]
956    Ident(Ident),
957}
958
959#[ast_node("ExtensionName")]
960#[derive(Eq, Hash)]
961pub struct ExtensionName {
962    pub span: Span,
963    pub value: Atom,
964    #[cfg_attr(
965        feature = "encoding-impl",
966        encoding(with = "cbor4ii::core::types::Maybe")
967    )]
968    pub raw: Option<Atom>,
969}
970
971impl EqIgnoreSpan for ExtensionName {
972    #[inline]
973    fn eq_ignore_span(&self, other: &Self) -> bool {
974        self.value == other.value
975    }
976}
977
978impl Take for ExtensionName {
979    #[inline]
980    fn dummy() -> Self {
981        Self {
982            span: Take::dummy(),
983            value: Default::default(),
984            raw: Take::dummy(),
985        }
986    }
987}
988
989#[ast_node("CustomMedia")]
990#[derive(Eq, Hash, EqIgnoreSpan)]
991pub struct CustomMediaQuery {
992    pub span: Span,
993    pub name: ExtensionName,
994    pub media: CustomMediaQueryMediaType,
995}
996
997impl Take for CustomMediaQuery {
998    #[inline]
999    fn dummy() -> Self {
1000        Self {
1001            span: Take::dummy(),
1002            name: Take::dummy(),
1003            media: Take::dummy(),
1004        }
1005    }
1006}
1007
1008#[ast_node(no_unknown)]
1009#[derive(Eq, Hash, Is, EqIgnoreSpan)]
1010pub enum CustomMediaQueryMediaType {
1011    #[tag("Ident")]
1012    Ident(Ident),
1013    #[tag("MediaQueryList")]
1014    MediaQueryList(MediaQueryList),
1015}
1016
1017impl Take for CustomMediaQueryMediaType {
1018    #[inline]
1019    fn dummy() -> Self {
1020        Self::Ident(Take::dummy())
1021    }
1022}