1use is_macro::Is;
2use swc_atoms::Atom;
3use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span};
4
5use crate::{
6 AlphaValue, AnglePercentage, AtRule, CalcSum, CmykComponent, Color, ComplexSelector,
7 DashedIdent, Delimiter, Dimension, FrequencyPercentage, Hue, IdSelector, Ident, Integer,
8 KeyframeBlock, LayerName, LengthPercentage, Number, Percentage, Ratio, RelativeSelectorList,
9 SelectorList, Str, SupportsCondition, TimePercentage, TokenAndSpan, UnicodeRange, Url,
10};
11
12#[ast_node("Stylesheet")]
13#[derive(Eq, Hash, EqIgnoreSpan)]
14pub struct Stylesheet {
15 pub span: Span,
16 pub rules: Vec<Rule>,
17}
18
19#[ast_node]
20#[derive(Eq, Hash, Is, EqIgnoreSpan)]
21pub enum Rule {
22 #[tag("QualifiedRule")]
23 QualifiedRule(Box<QualifiedRule>),
24
25 #[tag("AtRule")]
26 AtRule(Box<AtRule>),
27
28 #[tag("ListOfComponentValues")]
29 ListOfComponentValues(Box<ListOfComponentValues>),
30}
31
32impl Take for Rule {
33 fn dummy() -> Self {
34 Self::QualifiedRule(Take::dummy())
35 }
36}
37
38#[ast_node("QualifiedRule")]
39#[derive(Eq, Hash, EqIgnoreSpan)]
40pub struct QualifiedRule {
41 pub span: Span,
42 pub prelude: QualifiedRulePrelude,
43 pub block: SimpleBlock,
44}
45
46impl Take for QualifiedRule {
47 fn dummy() -> Self {
48 Self {
49 span: Take::dummy(),
50 prelude: Take::dummy(),
51 block: Take::dummy(),
52 }
53 }
54}
55
56#[ast_node]
57#[derive(Eq, Hash, Is, EqIgnoreSpan)]
58pub enum QualifiedRulePrelude {
59 #[tag("SelectorList")]
60 SelectorList(SelectorList),
61 #[tag("RelativeSelectorList")]
62 RelativeSelectorList(RelativeSelectorList),
63 #[tag("ListOfComponentValues")]
64 ListOfComponentValues(ListOfComponentValues),
65}
66
67impl Take for QualifiedRulePrelude {
68 fn dummy() -> Self {
69 Self::SelectorList(Take::dummy())
70 }
71}
72
73#[ast_node]
74#[derive(Eq, Hash, Is, EqIgnoreSpan)]
75pub enum StyleBlock {
76 #[tag("AtRule")]
77 AtRule(Box<AtRule>),
78 #[tag("Declaration")]
79 Declaration(Box<Declaration>),
80 #[tag("QualifiedRule")]
81 QualifiedRule(Box<QualifiedRule>),
82 #[tag("ListOfComponentValues")]
83 ListOfComponentValues(Box<ListOfComponentValues>),
84}
85
86#[ast_node("SimpleBlock")]
87#[derive(Eq, Hash, EqIgnoreSpan)]
88pub struct SimpleBlock {
89 pub span: Span,
90 pub name: TokenAndSpan,
91 pub value: Vec<ComponentValue>,
92}
93
94impl Take for SimpleBlock {
95 fn dummy() -> Self {
96 Self {
97 span: Take::dummy(),
98 name: Take::dummy(),
99 value: Take::dummy(),
100 }
101 }
102}
103
104#[ast_node]
105#[derive(Eq, Hash, Is, EqIgnoreSpan)]
106pub enum FunctionName {
107 #[tag("Ident")]
108 Ident(Ident),
109 #[tag("DashedIdent")]
110 DashedIdent(DashedIdent),
111}
112
113impl PartialEq<str> for FunctionName {
114 fn eq(&self, other: &str) -> bool {
115 match self {
116 FunctionName::DashedIdent(v) => *v == *other,
117 FunctionName::Ident(v) => *v == *other,
118 }
119 }
120}
121
122impl PartialEq<&'_ str> for FunctionName {
123 fn eq(&self, other: &&str) -> bool {
124 match self {
125 FunctionName::DashedIdent(v) => *v == **other,
126 FunctionName::Ident(v) => *v == **other,
127 }
128 }
129}
130
131impl PartialEq<Atom> for FunctionName {
132 fn eq(&self, other: &Atom) -> bool {
133 match self {
134 FunctionName::DashedIdent(v) => v.value == *other,
135 FunctionName::Ident(v) => v.value == *other,
136 }
137 }
138}
139
140impl FunctionName {
141 pub fn as_str(&self) -> &str {
142 match self {
143 FunctionName::DashedIdent(v) => &v.value,
144 FunctionName::Ident(v) => &v.value,
145 }
146 }
147}
148
149#[ast_node("Function")]
150#[derive(Eq, Hash, EqIgnoreSpan)]
151pub struct Function {
152 pub span: Span,
154 pub name: FunctionName,
155 pub value: Vec<ComponentValue>,
156}
157
158#[ast_node("ListOfComponentValues")]
159#[derive(Eq, Hash, EqIgnoreSpan)]
160pub struct ListOfComponentValues {
161 pub span: Span,
162 pub children: Vec<ComponentValue>,
163}
164
165#[ast_node]
166#[derive(Eq, Hash, Is, EqIgnoreSpan)]
167pub enum ComponentValue {
168 #[tag("TokenAndSpan")]
170 PreservedToken(Box<TokenAndSpan>),
171 #[tag("Function")]
172 Function(Box<Function>),
173 #[tag("SimpleBlock")]
174 SimpleBlock(Box<SimpleBlock>),
175
176 #[tag("AtRule")]
177 AtRule(Box<AtRule>),
178
179 #[tag("QualifiedRule")]
180 QualifiedRule(Box<QualifiedRule>),
181
182 #[tag("ListOfComponentValues")]
183 ListOfComponentValues(Box<ListOfComponentValues>),
184
185 #[tag("KeyframeBlock")]
186 KeyframeBlock(Box<KeyframeBlock>),
187
188 #[tag("Ident")]
190 Ident(Box<Ident>),
191 #[tag("DashedIdent")]
192 DashedIdent(Box<DashedIdent>),
193 #[tag("String")]
194 Str(Box<Str>),
195 #[tag("Url")]
196 Url(Box<Url>),
197 #[tag("Integer")]
198 Integer(Box<Integer>),
199 #[tag("Number")]
200 Number(Box<Number>),
201 #[tag("Percentage")]
202 Percentage(Box<Percentage>),
203 #[tag("Dimension")]
204 Dimension(Box<Dimension>),
205 #[tag("LengthPercentage")]
206 LengthPercentage(Box<LengthPercentage>),
207 #[tag("FrequencyPercentage")]
208 FrequencyPercentage(Box<FrequencyPercentage>),
209 #[tag("AnglePercentage")]
210 AnglePercentage(Box<AnglePercentage>),
211 #[tag("TimePercentage")]
212 TimePercentage(Box<TimePercentage>),
213 #[tag("Ratio")]
214 Ratio(Box<Ratio>),
215 #[tag("UnicodeRange")]
216 UnicodeRange(Box<UnicodeRange>),
217 #[tag("Color")]
218 Color(Box<Color>),
219 #[tag("AlphaValue")]
220 AlphaValue(Box<AlphaValue>),
221 #[tag("Hue")]
222 Hue(Box<Hue>),
223 #[tag("CmykComponent")]
224 CmykComponent(Box<CmykComponent>),
225 #[tag("Delimiter")]
226 Delimiter(Box<Delimiter>),
227
228 #[tag("CalcSum")]
230 CalcSum(Box<CalcSum>),
231 #[tag("ComplexSelector")]
232 ComplexSelector(Box<ComplexSelector>),
233 #[tag("LayerName")]
234 LayerName(Box<LayerName>),
235 #[tag("SupportsCondition")]
236 SupportsCondition(Box<SupportsCondition>),
237 #[tag("Declaration")]
238 Declaration(Box<Declaration>),
239 #[tag("IdSelector")]
240 IdSelector(Box<IdSelector>),
241}
242
243impl From<StyleBlock> for ComponentValue {
244 #[inline]
245 fn from(block: StyleBlock) -> Self {
246 match block {
247 StyleBlock::AtRule(at_rule) => ComponentValue::AtRule(at_rule),
248 StyleBlock::Declaration(declaration) => ComponentValue::Declaration(declaration),
249 StyleBlock::QualifiedRule(qualified_rule) => {
250 ComponentValue::QualifiedRule(qualified_rule)
251 }
252 StyleBlock::ListOfComponentValues(list_of_component_values) => {
253 ComponentValue::ListOfComponentValues(list_of_component_values)
254 }
255 }
256 }
257}
258
259impl From<DeclarationOrAtRule> for ComponentValue {
260 #[inline]
261 fn from(rule: DeclarationOrAtRule) -> Self {
262 match rule {
263 DeclarationOrAtRule::Declaration(declaration) => {
264 ComponentValue::Declaration(declaration)
265 }
266 DeclarationOrAtRule::AtRule(at_rule) => ComponentValue::AtRule(at_rule),
267 DeclarationOrAtRule::ListOfComponentValues(list_of_component_values) => {
268 ComponentValue::ListOfComponentValues(list_of_component_values)
269 }
270 }
271 }
272}
273
274impl From<Rule> for ComponentValue {
275 #[inline]
276 fn from(rule: Rule) -> Self {
277 match rule {
278 Rule::AtRule(at_rule) => ComponentValue::AtRule(at_rule),
279 Rule::QualifiedRule(qualified_rule) => ComponentValue::QualifiedRule(qualified_rule),
280 Rule::ListOfComponentValues(list_of_component_values) => {
281 ComponentValue::ListOfComponentValues(list_of_component_values)
282 }
283 }
284 }
285}
286
287#[ast_node]
288#[derive(Eq, Hash, Is, EqIgnoreSpan)]
289pub enum DeclarationOrAtRule {
290 #[tag("Declaration")]
291 Declaration(Box<Declaration>),
292 #[tag("AtRule")]
293 AtRule(Box<AtRule>),
294 #[tag("ListOfComponentValues")]
296 ListOfComponentValues(Box<ListOfComponentValues>),
297}
298
299#[ast_node("Declaration")]
300#[derive(Eq, Hash, EqIgnoreSpan)]
301pub struct Declaration {
302 pub span: Span,
303 pub name: DeclarationName,
304 pub value: Vec<ComponentValue>,
305 pub important: Option<ImportantFlag>,
307}
308
309#[ast_node]
310#[derive(Eq, Hash, Is, EqIgnoreSpan)]
311pub enum DeclarationName {
312 #[tag("Ident")]
313 Ident(Ident),
314 #[tag("DashedIdent")]
315 DashedIdent(DashedIdent),
316}
317
318impl PartialEq<str> for DeclarationName {
319 fn eq(&self, other: &str) -> bool {
320 match self {
321 DeclarationName::DashedIdent(v) => *v == *other,
322 DeclarationName::Ident(v) => *v == *other,
323 }
324 }
325}
326
327impl PartialEq<Atom> for DeclarationName {
328 fn eq(&self, other: &Atom) -> bool {
329 match self {
330 DeclarationName::DashedIdent(v) => v.value == *other,
331 DeclarationName::Ident(v) => v.value == *other,
332 }
333 }
334}
335
336#[ast_node("ImportantFlag")]
337#[derive(Eq, Hash, EqIgnoreSpan)]
338pub struct ImportantFlag {
339 pub span: Span,
340 pub value: Ident,
341}