1use std::hash::{Hash, Hasher};
2
3use is_macro::Is;
4use string_enum::StringEnum;
5use swc_atoms::Atom;
6use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span};
7
8use crate::Function;
9
10#[ast_node("Ident")]
11#[derive(Eq, PartialOrd, Ord, Hash)]
12pub struct Ident {
13 pub span: Span,
14
15 pub value: Atom,
16 pub raw: Option<Atom>,
17}
18
19impl EqIgnoreSpan for Ident {
20 #[inline]
21 fn eq_ignore_span(&self, other: &Self) -> bool {
22 self.value == other.value
23 }
24}
25
26impl PartialEq<str> for Ident {
27 #[inline]
28 fn eq(&self, other: &str) -> bool {
29 &*self.value == other
30 }
31}
32
33impl Take for Ident {
34 #[inline]
35 fn dummy() -> Self {
36 Self {
37 span: Default::default(),
38 value: Default::default(),
39 raw: Default::default(),
40 }
41 }
42}
43
44#[ast_node("CustomIdent")]
45#[derive(Eq, Hash)]
46pub struct CustomIdent {
47 pub span: Span,
48
49 pub value: Atom,
50 pub raw: Option<Atom>,
51}
52
53impl EqIgnoreSpan for CustomIdent {
54 #[inline]
55 fn eq_ignore_span(&self, other: &Self) -> bool {
56 self.value == other.value
57 }
58}
59
60#[ast_node("DashedIdent")]
61#[derive(Eq, Hash)]
62pub struct DashedIdent {
63 pub span: Span,
64
65 pub value: Atom,
66 pub raw: Option<Atom>,
67}
68
69impl EqIgnoreSpan for DashedIdent {
70 #[inline]
71 fn eq_ignore_span(&self, other: &Self) -> bool {
72 self.value == other.value
73 }
74}
75
76impl PartialEq<str> for DashedIdent {
77 #[inline]
78 fn eq(&self, other: &str) -> bool {
79 &*self.value == other
80 }
81}
82
83#[ast_node("CustomPropertyName")]
84#[derive(Eq, Hash)]
85pub struct CustomPropertyName {
86 pub span: Span,
87
88 pub value: Atom,
89 pub raw: Option<Atom>,
90}
91
92impl EqIgnoreSpan for CustomPropertyName {
93 fn eq_ignore_span(&self, other: &Self) -> bool {
94 self.value == other.value
95 }
96}
97
98#[ast_node("String")]
100#[derive(Eq, Hash)]
101pub struct Str {
102 pub span: Span,
103
104 pub value: Atom,
105 pub raw: Option<Atom>,
106}
107
108impl EqIgnoreSpan for Str {
109 fn eq_ignore_span(&self, other: &Self) -> bool {
110 self.value == other.value
111 }
112}
113
114#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, Is, EqIgnoreSpan)]
115#[cfg_attr(
116 feature = "rkyv",
117 derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
118)]
119#[cfg_attr(
120 feature = "rkyv",
121 rkyv(serialize_bounds(__S: rkyv::ser::Writer + rkyv::ser::Allocator,
122 __S::Error: rkyv::rancor::Source))
123)]
124#[cfg_attr(feature = "rkyv", derive(bytecheck::CheckBytes))]
125#[cfg_attr(feature = "rkyv", repr(u32))]
126pub enum DelimiterValue {
127 Comma,
129 Solidus,
131 Semicolon,
133}
134
135#[ast_node("Delimiter")]
136#[derive(Eq, Hash, EqIgnoreSpan)]
137pub struct Delimiter {
138 pub span: Span,
139 pub value: DelimiterValue,
140}
141
142#[ast_node]
145#[derive(Eq, Hash, Is, EqIgnoreSpan)]
146pub enum Color {
147 #[tag("AbsoluteColorBase")]
148 AbsoluteColorBase(AbsoluteColorBase),
149 #[tag("Ident")]
150 CurrentColorOrSystemColor(Ident),
151 #[tag("Function")]
153 Function(Function),
154}
155
156#[ast_node]
157#[derive(Eq, Hash, Is, EqIgnoreSpan)]
158pub enum AbsoluteColorBase {
159 #[tag("HexColor")]
160 HexColor(HexColor),
161 #[tag("Ident")]
162 NamedColorOrTransparent(Ident),
163 #[tag("Function")]
164 Function(Function),
165}
166
167#[ast_node("HexColor")]
168#[derive(Eq, Hash, EqIgnoreSpan)]
169pub struct HexColor {
170 pub span: Span,
172 pub value: Atom,
174 pub raw: Option<Atom>,
176}
177
178#[ast_node]
179#[derive(Eq, Hash, Is, EqIgnoreSpan)]
180pub enum AlphaValue {
181 #[tag("Number")]
182 Number(Number),
183 #[tag("Percentage")]
184 Percentage(Percentage),
185}
186
187#[ast_node]
188#[derive(Eq, Hash, Is, EqIgnoreSpan)]
189pub enum Hue {
190 #[tag("Number")]
191 Number(Number),
192 #[tag("Angle")]
193 Angle(Angle),
194}
195
196#[ast_node]
197#[derive(Eq, Hash, Is, EqIgnoreSpan)]
198pub enum CmykComponent {
199 #[tag("Number")]
200 Number(Number),
201 #[tag("Percentage")]
202 Percentage(Percentage),
203 #[tag("Function")]
204 Function(Function),
205}
206
207#[ast_node]
208#[derive(Eq, Hash, Is, EqIgnoreSpan)]
209pub enum Dimension {
210 #[tag("Length")]
211 Length(Length),
212
213 #[tag("Angle")]
214 Angle(Angle),
215
216 #[tag("Time")]
217 Time(Time),
218
219 #[tag("Frequency")]
220 Frequency(Frequency),
221
222 #[tag("Resolution")]
223 Resolution(Resolution),
224
225 #[tag("Flex")]
226 Flex(Flex),
227
228 #[tag("UnknownDimension")]
229 UnknownDimension(UnknownDimension),
230}
231
232#[ast_node("Length")]
233#[derive(Eq, Hash, EqIgnoreSpan)]
234pub struct Length {
235 pub span: Span,
236 pub value: Number,
237 pub unit: Ident,
238}
239
240#[ast_node("Angle")]
241#[derive(Eq, Hash, EqIgnoreSpan)]
242pub struct Angle {
243 pub span: Span,
244 pub value: Number,
245 pub unit: Ident,
246}
247
248#[ast_node("Time")]
249#[derive(Eq, Hash, EqIgnoreSpan)]
250pub struct Time {
251 pub span: Span,
252 pub value: Number,
253 pub unit: Ident,
254}
255
256#[ast_node("Frequency")]
257#[derive(Eq, Hash, EqIgnoreSpan)]
258pub struct Frequency {
259 pub span: Span,
260 pub value: Number,
261 pub unit: Ident,
262}
263
264#[ast_node("Resolution")]
265#[derive(Eq, Hash, EqIgnoreSpan)]
266pub struct Resolution {
267 pub span: Span,
268 pub value: Number,
269 pub unit: Ident,
270}
271
272#[ast_node("Flex")]
273#[derive(Eq, Hash, EqIgnoreSpan)]
274pub struct Flex {
275 pub span: Span,
276 pub value: Number,
277 pub unit: Ident,
278}
279
280#[ast_node("UnknownDimension")]
281#[derive(Eq, Hash, EqIgnoreSpan)]
282pub struct UnknownDimension {
283 pub span: Span,
284 pub value: Number,
285 pub unit: Ident,
286}
287
288#[ast_node("Percentage")]
289#[derive(Eq, Hash, EqIgnoreSpan)]
290pub struct Percentage {
291 pub span: Span,
292 pub value: Number,
293}
294
295#[ast_node]
296#[derive(Eq, Hash, Is, EqIgnoreSpan)]
297pub enum LengthPercentage {
298 #[tag("Length")]
299 Length(Length),
300 #[tag("Percentage")]
301 Percentage(Percentage),
302}
303
304#[ast_node]
305#[derive(Eq, Hash, Is, EqIgnoreSpan)]
306pub enum FrequencyPercentage {
307 #[tag("Frequency")]
308 Frequency(Frequency),
309 #[tag("Percentage")]
310 Percentage(Percentage),
311}
312
313#[ast_node]
314#[derive(Eq, Hash, Is, EqIgnoreSpan)]
315pub enum AnglePercentage {
316 #[tag("Angle")]
317 Angle(Angle),
318 #[tag("Percentage")]
319 Percentage(Percentage),
320}
321
322#[ast_node]
323#[derive(Eq, Hash, Is, EqIgnoreSpan)]
324pub enum TimePercentage {
325 #[tag("Time")]
326 Time(Time),
327 #[tag("Percentage")]
328 Percentage(Percentage),
329}
330
331#[ast_node("Integer")]
332#[derive(Eq, Hash)]
333pub struct Integer {
334 pub span: Span,
335 pub value: i64,
336 pub raw: Option<Atom>,
337}
338
339impl EqIgnoreSpan for Integer {
340 fn eq_ignore_span(&self, other: &Self) -> bool {
341 self.value == other.value
342 }
343}
344
345#[ast_node("Number")]
346pub struct Number {
347 pub span: Span,
348 pub value: f64,
349 pub raw: Option<Atom>,
350}
351
352impl Eq for Number {}
353
354#[allow(clippy::derived_hash_with_manual_eq)]
355#[allow(clippy::transmute_float_to_int)]
356impl Hash for Number {
357 fn hash<H: Hasher>(&self, state: &mut H) {
358 fn integer_decode(val: f64) -> (u64, i16, i8) {
359 let bits: u64 = f64::to_bits(val);
360 let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
361 let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
362 let mantissa = if exponent == 0 {
363 (bits & 0xfffffffffffff) << 1
364 } else {
365 (bits & 0xfffffffffffff) | 0x10000000000000
366 };
367
368 exponent -= 1023 + 52;
369 (mantissa, exponent, sign)
370 }
371
372 self.span.hash(state);
373 integer_decode(self.value).hash(state);
374 }
375}
376
377impl EqIgnoreSpan for Number {
378 fn eq_ignore_span(&self, other: &Self) -> bool {
379 self.value == other.value
380 }
381}
382
383#[ast_node("Ratio")]
384#[derive(Eq, Hash, EqIgnoreSpan)]
385pub struct Ratio {
386 pub span: Span,
387 pub left: Number,
388 pub right: Option<Number>,
389}
390
391#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, Is, EqIgnoreSpan)]
392#[cfg_attr(
393 feature = "rkyv",
394 derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
395)]
396#[cfg_attr(
397 feature = "rkyv",
398 rkyv(serialize_bounds(__S: rkyv::ser::Writer + rkyv::ser::Allocator,
399 __S::Error: rkyv::rancor::Source))
400)]
401#[cfg_attr(feature = "rkyv", derive(bytecheck::CheckBytes))]
402#[cfg_attr(feature = "rkyv", repr(u32))]
403pub enum BinOp {
404 Add,
406 Sub,
408 Mul,
410 Div,
412}
413
414#[ast_node("Url")]
415#[derive(Eq, Hash, EqIgnoreSpan)]
416pub struct Url {
417 pub span: Span,
418 pub name: Ident,
419 pub value: Option<Box<UrlValue>>,
420 pub modifiers: Option<Vec<UrlModifier>>,
421}
422
423#[ast_node]
424#[derive(Eq, Hash, Is, EqIgnoreSpan)]
425pub enum UrlValue {
426 #[tag("Str")]
427 Str(Str),
428 #[tag("UrlValueRaw")]
429 Raw(UrlValueRaw),
430}
431
432#[ast_node("UrlValueRaw")]
433#[derive(Eq, Hash, EqIgnoreSpan)]
434pub struct UrlValueRaw {
435 pub span: Span,
436
437 pub value: Atom,
438 pub raw: Option<Atom>,
439}
440
441#[ast_node]
442#[derive(Eq, Hash, Is, EqIgnoreSpan)]
443pub enum UrlModifier {
444 #[tag("Ident")]
445 Ident(Ident),
446 #[tag("Function")]
447 Function(Function),
448}
449
450#[ast_node("UnicodeRange")]
451#[derive(Eq, Hash)]
452pub struct UnicodeRange {
453 pub span: Span,
454
455 pub start: Atom,
456
457 pub end: Option<Atom>,
458 pub raw: Option<Atom>,
459}
460
461impl EqIgnoreSpan for UnicodeRange {
462 #[inline]
463 fn eq_ignore_span(&self, other: &Self) -> bool {
464 self.start == other.start && self.end == other.end
465 }
466}
467
468#[ast_node("CalcSum")]
469#[derive(Eq, Hash, EqIgnoreSpan)]
470pub struct CalcSum {
471 pub span: Span,
472 pub expressions: Vec<CalcProductOrOperator>,
473}
474
475#[ast_node]
476#[derive(Eq, Hash, Is, EqIgnoreSpan)]
477pub enum CalcProductOrOperator {
478 #[tag("CalcProduct")]
479 Product(CalcProduct),
480 #[tag("CalcOperator")]
481 Operator(CalcOperator),
482}
483
484#[ast_node("CalcProduct")]
485#[derive(Eq, Hash, EqIgnoreSpan)]
486pub struct CalcProduct {
487 pub span: Span,
488 pub expressions: Vec<CalcValueOrOperator>,
489}
490
491#[ast_node("CalcOperator")]
492#[derive(Eq, Hash, EqIgnoreSpan)]
493pub struct CalcOperator {
494 pub span: Span,
495 pub value: CalcOperatorType,
496}
497
498#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, Is, EqIgnoreSpan)]
499#[cfg_attr(
500 feature = "rkyv",
501 derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
502)]
503#[cfg_attr(
504 feature = "rkyv",
505 rkyv(serialize_bounds(__S: rkyv::ser::Writer + rkyv::ser::Allocator,
506 __S::Error: rkyv::rancor::Source))
507)]
508#[cfg_attr(feature = "rkyv-impl", derive(bytecheck::CheckBytes))]
509#[cfg_attr(feature = "rkyv-impl", repr(u32))]
510pub enum CalcOperatorType {
511 Add,
513 Sub,
515 Mul,
517 Div,
519}
520
521#[ast_node]
522#[derive(Eq, Hash, Is, EqIgnoreSpan)]
523pub enum CalcValueOrOperator {
524 #[tag("CalcValue")]
525 Value(CalcValue),
526 #[tag("CalcOperator")]
527 Operator(CalcOperator),
528}
529
530#[ast_node]
531#[derive(Eq, Hash, Is, EqIgnoreSpan)]
532pub enum CalcValue {
533 #[tag("Number")]
534 Number(Number),
535 #[tag("Dimension")]
536 Dimension(Dimension),
537 #[tag("Percentage")]
538 Percentage(Percentage),
539 #[tag("Ident")]
540 Constant(Ident),
541 #[tag("CalcSum")]
542 Sum(CalcSum),
543 #[tag("Function")]
544 Function(Function),
545}
546
547#[ast_node]
548#[derive(Eq, Hash, Is, EqIgnoreSpan)]
549pub enum FamilyName {
550 #[tag("Str")]
551 Str(Str),
552 #[tag("SequenceOfCustomIdents")]
553 SequenceOfCustomIdents(SequenceOfCustomIdents),
554}
555
556#[ast_node("SequenceOfCustomIdents")]
557#[derive(Eq, Hash, EqIgnoreSpan)]
558pub struct SequenceOfCustomIdents {
559 pub span: Span,
560 pub value: Vec<CustomIdent>,
561}