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