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