1use crate::{Cursor, CursorSink, Kind, KindSet, Parse, Parser, Peek, Result, Span, ToNumberValue, Token};
2
3macro_rules! cursor_wrapped {
4 ($ident:ident) => {
5 impl $crate::ToCursors for $ident {
6 fn to_cursors(&self, s: &mut impl CursorSink) {
7 s.append((*self).into());
8 }
9 }
10
11 impl From<$ident> for $crate::Cursor {
12 fn from(value: $ident) -> Self {
13 value.0.into()
14 }
15 }
16
17 impl From<$ident> for $crate::Token {
18 fn from(value: $ident) -> Self {
19 value.0.into()
20 }
21 }
22
23 impl $crate::ToSpan for $ident {
24 fn to_span(&self) -> Span {
25 self.0.to_span()
26 }
27 }
28
29 impl $crate::SemanticEq for $ident {
30 fn semantic_eq(&self, s: &Self) -> bool {
31 self.0.semantic_eq(&s.0)
32 }
33 }
34 };
35}
36
37macro_rules! define_kinds {
38 ($($(#[$meta:meta])* $ident:ident,)*) => {
39 $(
40 $(#[$meta])*
41 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
42 #[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
43 pub struct $ident($crate::Cursor);
44
45 impl $ident {
46 pub const fn dummy() -> Self {
47 Self($crate::Cursor::dummy($crate::Token::dummy($crate::Kind::$ident)))
48 }
49
50 pub fn associated_whitespace(&self) -> $crate::AssociatedWhitespaceRules {
51 self.0.token().associated_whitespace()
52 }
53
54 pub fn with_associated_whitespace(&self, rules: $crate::AssociatedWhitespaceRules) -> Self {
55 Self(self.0.with_associated_whitespace(rules))
56 }
57 }
58
59 impl $crate::ToCursors for $ident {
60 fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
61 s.append((*self).into());
62 }
63 }
64
65 impl<'a> $crate::Peek<'a> for $ident {
66 fn peek<I>(_: &$crate::Parser<'a, I>, c: $crate::Cursor) -> bool
67 where
68 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
69 {
70 c == $crate::Kind::$ident
71 }
72 }
73
74 impl<'a> $crate::Parse<'a> for $ident {
75 fn parse<I>(p: &mut $crate::Parser<'a, I>) -> $crate::Result<Self>
76 where
77 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
78 {
79 let c = p.next();
80 if Self::peek(p, c) { Ok(Self(c)) } else { Err($crate::Diagnostic::new(c, $crate::Diagnostic::unexpected))? }
81 }
82 }
83
84
85 impl From<$ident> for $crate::Cursor {
86 fn from(value: $ident) -> Self {
87 value.0.into()
88 }
89 }
90
91 impl From<$ident> for $crate::Token {
92 fn from(value: $ident) -> Self {
93 value.0.into()
94 }
95 }
96
97 impl $crate::ToSpan for $ident {
98 fn to_span(&self) -> $crate::Span {
99 self.0.to_span()
100 }
101 }
102
103 impl $crate::SemanticEq for $ident {
104 fn semantic_eq(&self, s: &Self) -> bool {
105 self.0.semantic_eq(&s.0)
106 }
107 }
108 )*
109 };
110}
111
112macro_rules! define_kind_idents {
113 ($($(#[$meta:meta])* $ident:ident,)*) => {
114 $(
115 $(#[$meta])*
116 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
117 #[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
118 pub struct $ident($crate::Cursor);
119
120 impl $crate::ToCursors for $ident {
121 fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
122 s.append((*self).into());
123 }
124 }
125
126 impl<'a> $crate::Peek<'a> for $ident {
127 fn peek<I>(_: &$crate::Parser<'a, I>, c: $crate::Cursor) -> bool
128 where
129 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
130 {
131 c == $crate::Kind::$ident
132 }
133 }
134
135 impl<'a> $crate::Parse<'a> for $ident {
136 fn parse<I>(p: &mut $crate::Parser<'a, I>) -> $crate::Result<Self>
137 where
138 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
139 {
140 let c = p.next();
141 if Self::peek(p, c) { Ok(Self(c)) } else { Err($crate::Diagnostic::new(c, $crate::Diagnostic::unexpected))? }
142 }
143 }
144
145
146 impl From<$ident> for $crate::Kind {
147 fn from(value: $ident) -> Self {
148 value.0.into()
149 }
150 }
151
152 impl From<$ident> for $crate::Cursor {
153 fn from(value: $ident) -> Self {
154 value.0
155 }
156 }
157
158 impl From<$ident> for $crate::Token {
159 fn from(value: $ident) -> Self {
160 value.0.into()
161 }
162 }
163
164 impl $crate::ToSpan for $ident {
165 fn to_span(&self) -> $crate::Span {
166 self.0.to_span()
167 }
168 }
169
170 impl $crate::SemanticEq for $ident {
171 fn semantic_eq(&self, s: &Self) -> bool {
172 self.0.semantic_eq(&s.0)
173 }
174 }
175
176 impl $ident {
177 pub fn is_dashed_ident(&self) -> bool {
179 self.0.token().is_dashed_ident()
180 }
181
182 pub const fn dummy() -> Self {
183 Self($crate::Cursor::dummy($crate::Token::dummy($crate::Kind::$ident)))
184 }
185 }
186 )*
187 };
188}
189
190#[macro_export]
205macro_rules! custom_delim {
206 ($(#[$meta:meta])* $ident:ident, $ch:literal) => {
207 $(#[$meta])*
208 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
209 #[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
210 pub struct $ident($crate::T![Delim]);
211
212 impl $crate::ToCursors for $ident {
213 fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
214 s.append((*self).into());
215 }
216 }
217
218 impl<'a> $crate::Peek<'a> for $ident {
219 fn peek<I>(_: &$crate::Parser<'a, I>, c: $crate::Cursor) -> bool
220 where
221 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
222 {
223 c == $crate::Kind::Delim && c == $ch
224 }
225 }
226
227 impl<'a> $crate::Parse<'a> for $ident {
228 fn parse<I>(p: &mut $crate::Parser<'a, I>) -> $crate::Result<Self>
229 where
230 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
231 {
232 use $crate::Peek;
233 let delim = p.parse::<$crate::T![Delim]>()?;
234 if Self::peek(p, delim.into()) {
235 Ok(Self(delim))
236 } else {
237 Err($crate::Diagnostic::new(delim.into(), $crate::Diagnostic::unexpected))?
238 }
239 }
240 }
241
242
243
244 impl From<$ident> for $crate::Cursor {
245 fn from(value: $ident) -> Self {
246 value.0.into()
247 }
248 }
249
250 impl $crate::ToSpan for $ident {
251 fn to_span(&self) -> $crate::Span {
252 self.0.to_span()
253 }
254 }
255
256 impl PartialEq<char> for $ident {
257 fn eq(&self, other: &char) -> bool {
258 self.0 == *other
259 }
260 }
261
262 impl $crate::SemanticEq for $ident {
263 fn semantic_eq(&self, other: &Self) -> bool {
264 self.0.semantic_eq(&other.0)
265 }
266 }
267 };
268}
269
270#[macro_export]
286macro_rules! custom_double_delim {
287 ($(#[$meta:meta])*$ident: ident, $first: literal, $second: literal) => {
288 $(#[$meta])*
289 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
290 #[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
291 pub struct $ident($crate::T![Delim], pub $crate::T![Delim]);
292
293 impl $ident {
294 pub const fn dummy() -> Self {
295 Self(<$crate::T![Delim]>::dummy(), <$crate::T![Delim]>::dummy())
296 }
297 }
298
299 impl<'a> $crate::Peek<'a> for $ident {
300 fn peek<I>(p: &$crate::Parser<'a, I>, c: $crate::Cursor) -> bool
301 where
302 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
303 {
304 c == $first && p.peek_n(2) == $second
305 }
306 }
307
308 impl<'a> $crate::Parse<'a> for $ident {
309 fn parse<I>(p: &mut $crate::Parser<'a, I>) -> $crate::Result<Self>
310 where
311 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
312 {
313 let first = p.parse::<$crate::T![Delim]>()?;
314 if first != $first {
315 let c: Cursor = first.into();
316 Err($crate::Diagnostic::new(c, $crate::Diagnostic::expected_delim))?;
317 }
318 let skip = p.set_skip($crate::KindSet::NONE);
319 let second = p.parse::<$crate::T![Delim]>();
320 p.set_skip(skip);
321 let second = second?;
322 if second != $second {
323 let c:Cursor = second.into();
324 Err($crate::Diagnostic::new(c, $crate::Diagnostic::expected_delim))?;
325 }
326 Ok(Self(first, second))
327 }
328 }
329
330 impl<'a> $crate::ToCursors for $ident {
331 fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
332 s.append(self.0.into());
333 s.append(self.1.into());
334 }
335 }
336
337 impl $crate::ToSpan for $ident {
338 fn to_span(&self) -> $crate::Span {
339 self.0.to_span() + self.1.to_span()
340 }
341 }
342
343 impl $crate::SemanticEq for $ident {
344 fn semantic_eq(&self, other: &Self) -> bool {
345 self.0.semantic_eq(&other.0) && self.1.semantic_eq(&other.1)
346 }
347 }
348 };
349}
350
351define_kinds! {
352 Eof,
354
355 Comment,
357
358 CdcOrCdo,
360
361 BadString,
363
364 BadUrl,
366
367 Delim,
369
370 Colon,
372
373 Semicolon,
375
376 Comma,
378
379 LeftCurly,
381
382 RightCurly,
384
385 LeftSquare,
387
388 RightSquare,
390
391 LeftParen,
393
394 RightParen,
396}
397
398impl PartialEq<char> for Delim {
399 fn eq(&self, other: &char) -> bool {
400 self.0 == *other
401 }
402}
403
404define_kind_idents! {
405 Ident,
407
408 String,
410
411 Url,
413
414 Function,
416
417 AtKeyword,
419
420 Hash,
422}
423
424#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
427#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
428pub struct Whitespace(Cursor);
429cursor_wrapped!(Whitespace);
430
431impl<'a> Peek<'a> for Whitespace {
432 fn peek<I>(p: &Parser<'a, I>, _: Cursor) -> bool
433 where
434 I: Iterator<Item = Cursor> + Clone,
435 {
436 let c = p.peek_n_with_skip(1, KindSet::COMMENTS);
438 c == Kind::Whitespace
439 }
440}
441
442impl<'a> Parse<'a> for Whitespace {
443 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
444 where
445 I: Iterator<Item = Cursor> + Clone,
446 {
447 let skip = p.set_skip(KindSet::COMMENTS);
450 let c = p.next();
451 p.set_skip(skip);
452 if c != Kind::Whitespace {
453 Err(crate::Diagnostic::new(c, crate::Diagnostic::unexpected))?
454 }
455 Ok(Self(c))
456 }
457}
458
459#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
462#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
463pub struct DashedIdent(Ident);
464cursor_wrapped!(DashedIdent);
465
466impl<'a> Peek<'a> for DashedIdent {
467 fn peek<I>(_: &Parser<'a, I>, c: Cursor) -> bool
468 where
469 I: Iterator<Item = Cursor> + Clone,
470 {
471 c == Kind::Ident && c.token().is_dashed_ident()
472 }
473}
474
475impl<'a> Parse<'a> for DashedIdent {
476 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
477 where
478 I: Iterator<Item = Cursor> + Clone,
479 {
480 let c = p.next();
481 if Self::peek(p, c) {
482 Ok(Self(Ident(c)))
483 } else {
484 Err(crate::Diagnostic::new(c, crate::Diagnostic::unexpected))?
485 }
486 }
487}
488
489#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
491#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
492pub struct Dimension(Cursor);
493cursor_wrapped!(Dimension);
494
495impl PartialEq<f32> for Dimension {
496 fn eq(&self, other: &f32) -> bool {
497 self.0.token().value() == *other
498 }
499}
500
501impl<'a> Peek<'a> for Dimension {
502 fn peek<I>(_: &Parser<'a, I>, c: Cursor) -> bool
503 where
504 I: Iterator<Item = Cursor> + Clone,
505 {
506 c == Kind::Dimension
507 }
508}
509
510impl<'a> Parse<'a> for Dimension {
511 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
512 where
513 I: Iterator<Item = Cursor> + Clone,
514 {
515 let c = p.next();
516 if Self::peek(p, c) { Ok(Self(c)) } else { Err(crate::Diagnostic::new(c, crate::Diagnostic::unexpected))? }
517 }
518}
519
520impl From<Dimension> for f32 {
521 fn from(val: Dimension) -> Self {
522 val.0.token().value()
523 }
524}
525
526impl ToNumberValue for Dimension {
527 fn to_number_value(&self) -> Option<f32> {
528 Some(self.0.token().value())
529 }
530}
531
532impl Dimension {
533 pub fn value(&self) -> f32 {
535 self.0.token().value()
536 }
537}
538
539#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
541#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
542pub struct Number(Cursor);
543cursor_wrapped!(Number);
544
545impl Number {
546 pub const NUMBER_ZERO: Number = Number(Cursor::dummy(Token::NUMBER_ZERO));
547 pub const ZERO: Number = Number(Cursor::dummy(Token::NUMBER_ZERO));
548
549 pub fn value(&self) -> f32 {
551 self.0.token().value()
552 }
553
554 pub fn is_int(&self) -> bool {
555 self.0.token().is_int()
556 }
557
558 pub fn is_float(&self) -> bool {
559 self.0.token().is_float()
560 }
561
562 pub fn has_sign(&self) -> bool {
563 self.0.token().has_sign()
564 }
565}
566
567impl<'a> Peek<'a> for Number {
568 fn peek<I>(_: &Parser<'a, I>, c: Cursor) -> bool
569 where
570 I: Iterator<Item = Cursor> + Clone,
571 {
572 c == Kind::Number
573 }
574}
575
576impl<'a> Parse<'a> for Number {
577 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
578 where
579 I: Iterator<Item = Cursor> + Clone,
580 {
581 let c = p.next();
582 if Self::peek(p, c) { Ok(Self(c)) } else { Err(crate::Diagnostic::new(c, crate::Diagnostic::unexpected))? }
583 }
584}
585
586impl From<Number> for f32 {
587 fn from(value: Number) -> Self {
588 value.value()
589 }
590}
591
592impl From<Number> for i32 {
593 fn from(value: Number) -> Self {
594 value.value() as i32
595 }
596}
597
598impl PartialEq<f32> for Number {
599 fn eq(&self, other: &f32) -> bool {
600 self.value() == *other
601 }
602}
603
604impl ToNumberValue for Number {
605 fn to_number_value(&self) -> Option<f32> {
606 Some(self.value())
607 }
608}
609
610pub mod delim {
612 custom_delim! {
613 And, '&'
616 }
617 custom_delim! {
618 At, '@'
622 }
623 custom_delim! {
624 Caret, '^'
627 }
628 custom_delim! {
629 Dash, '-'
632 }
633 custom_delim! {
634 Dollar, '$'
637 }
638 custom_delim! {
639 Dot, '.'
642 }
643 custom_delim! {
644 Eq, '='
647 }
648 custom_delim! {
649 Gt, '>'
652 }
653 custom_delim! {
654 Hash, '#'
658 }
659 custom_delim! {
660 Lt, '<'
663 }
664 custom_delim! {
665 Bang, '!'
668 }
669 custom_delim! {
670 Or, '|'
673 }
674 custom_delim! {
675 Percent, '%'
678 }
679 custom_delim! {
680 Plus, '+'
683 }
684 custom_delim! {
685 Question, '?'
688 }
689 custom_delim! {
690 Slash, '/'
693 }
694 custom_delim! {
695 Star, '*'
698 }
699 custom_delim! {
700 Tilde, '~'
703 }
704 custom_delim! {
705 Underscore, '_'
708 }
709 custom_delim! {
710 Backtick, '`'
713 }
714}
715
716pub mod double {
720 use crate::{
721 Cursor, CursorSink, Kind, KindSet, Parse, Parser, Peek, Result, SemanticEq, Span, T, ToCursors, ToSpan,
722 };
723
724 custom_double_delim! {
725 GreaterThanEqual, '>', '='
729 }
730 custom_double_delim! {
731 LessThanEqual, '<', '='
735 }
736 custom_double_delim! {
737 StarPipe, '*', '|'
741 }
742 custom_double_delim! {
743 PipePipe, '|', '|'
747 }
748 custom_double_delim! {
749 EqualEqual, '=', '='
753 }
754 custom_double_delim! {
755 TildeEqual, '~', '='
759 }
760 custom_double_delim! {
761 PipeEqual, '|', '='
765 }
766 custom_double_delim! {
767 CaretEqual, '^', '='
771 }
772 custom_double_delim! {
773 DollarEqual, '$', '='
777 }
778 custom_double_delim! {
779 StarEqual, '*', '='
783 }
784 custom_double_delim! {
785 BangEqual, '*', '='
789 }
790
791 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
794 #[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
795 pub struct ColonColon(T![:], T![:]);
796
797 impl ColonColon {
798 pub const fn dummy() -> Self {
799 Self(<T![:]>::dummy(), <T![:]>::dummy())
800 }
801 }
802
803 impl<'a> Peek<'a> for ColonColon {
804 fn peek<I>(p: &Parser<'a, I>, c: Cursor) -> bool
805 where
806 I: Iterator<Item = Cursor> + Clone,
807 {
808 c == Kind::Colon && p.peek_n(2) == Kind::Colon
809 }
810 }
811
812 impl<'a> Parse<'a> for ColonColon {
813 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
814 where
815 I: Iterator<Item = Cursor> + Clone,
816 {
817 let first = p.parse::<T![:]>()?;
818 let skip = p.set_skip(KindSet::NONE);
819 let second = p.parse::<T![:]>();
820 p.set_skip(skip);
821 Ok(Self(first, second?))
822 }
823 }
824
825 impl ToCursors for ColonColon {
826 fn to_cursors(&self, s: &mut impl CursorSink) {
827 s.append(self.0.into());
828 s.append(self.1.into());
829 }
830 }
831
832 impl ToSpan for ColonColon {
833 fn to_span(&self) -> Span {
834 self.0.to_span() + self.1.to_span()
835 }
836 }
837
838 impl SemanticEq for ColonColon {
839 fn semantic_eq(&self, other: &Self) -> bool {
840 self.0.semantic_eq(&other.0) && self.1.semantic_eq(&other.1)
841 }
842 }
843}
844
845#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
847#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
848pub struct Any(Cursor);
849cursor_wrapped!(Any);
850
851impl<'a> Peek<'a> for Any {
852 fn peek<I>(_: &Parser<'a, I>, _: Cursor) -> bool
853 where
854 I: Iterator<Item = Cursor> + Clone,
855 {
856 true
857 }
858}
859
860impl<'a> Parse<'a> for Any {
861 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
862 where
863 I: Iterator<Item = Cursor> + Clone,
864 {
865 let c = p.next();
866 Ok(Self(c))
867 }
868}
869
870#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
873#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
874pub struct PairWiseStart(Cursor);
875cursor_wrapped!(PairWiseStart);
876
877impl PairWiseStart {
878 pub fn kind(&self) -> Kind {
879 self.0.token().kind()
880 }
881
882 pub fn end(&self) -> Kind {
883 match self.kind() {
884 Kind::LeftCurly => Kind::RightCurly,
885 Kind::LeftParen => Kind::RightParen,
886 Kind::LeftSquare => Kind::RightSquare,
887 k => k,
888 }
889 }
890}
891
892impl<'a> Peek<'a> for PairWiseStart {
893 const PEEK_KINDSET: KindSet = KindSet::new(&[Kind::LeftCurly, Kind::LeftSquare, Kind::LeftParen]);
894}
895
896impl<'a> Parse<'a> for PairWiseStart {
897 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
898 where
899 I: Iterator<Item = Cursor> + Clone,
900 {
901 let c = p.next();
902 if Self::peek(p, c) { Ok(Self(c)) } else { Err(crate::Diagnostic::new(c, crate::Diagnostic::unexpected))? }
903 }
904}
905
906#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
909#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
910pub struct PairWiseEnd(Cursor);
911cursor_wrapped!(PairWiseEnd);
912
913impl PairWiseEnd {
914 pub fn kind(&self) -> Kind {
915 self.0.token().kind()
916 }
917
918 pub fn start(&self) -> Kind {
919 match self.kind() {
920 Kind::RightCurly => Kind::LeftCurly,
921 Kind::RightParen => Kind::LeftParen,
922 Kind::RightSquare => Kind::LeftSquare,
923 k => k,
924 }
925 }
926}
927
928impl<'a> Peek<'a> for PairWiseEnd {
929 const PEEK_KINDSET: KindSet = KindSet::new(&[Kind::RightCurly, Kind::RightSquare, Kind::RightParen]);
930}
931
932impl<'a> Parse<'a> for PairWiseEnd {
933 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
934 where
935 I: Iterator<Item = Cursor> + Clone,
936 {
937 let c = p.next();
938 if Self::peek(p, c) { Ok(Self(c)) } else { Err(crate::Diagnostic::new(c, crate::Diagnostic::unexpected))? }
939 }
940}
941
942#[macro_export]
945macro_rules! T {
946 [:] => { $crate::token_macros::Colon };
947 [;] => { $crate::token_macros::Semicolon };
948 [,] => { $crate::token_macros::Comma };
949 ['{'] => { $crate::token_macros::LeftCurly };
950 ['}'] => { $crate::token_macros::RightCurly };
951 ['['] => { $crate::token_macros::LeftSquare };
952 [']'] => { $crate::token_macros::RightSquare };
953 ['('] => { $crate::token_macros::LeftParen };
954 [')'] => { $crate::token_macros::RightParen };
955 [' '] => { $crate::token_macros::Whitespace };
956
957 [&] => { $crate::token_macros::delim::And };
958 [@] => { $crate::token_macros::delim::At };
959 [^] => { $crate::token_macros::delim::Caret };
960 [-] => { $crate::token_macros::delim::Dash };
961 [$] => { $crate::token_macros::delim::Dollar };
962 [.] => { $crate::token_macros::delim::Dot };
963 [=] => { $crate::token_macros::delim::Eq };
964 [>] => { $crate::token_macros::delim::Gt };
965 [#] => { $crate::token_macros::delim::Hash };
966 [<] => { $crate::token_macros::delim::Lt };
967 [!] => { $crate::token_macros::delim::Bang };
968 [|] => { $crate::token_macros::delim::Or };
969 [%] => { $crate::token_macros::delim::Percent };
970 [+] => { $crate::token_macros::delim::Plus };
971 [?] => { $crate::token_macros::delim::Question };
972 [/] => { $crate::token_macros::delim::Slash };
973 [*] => { $crate::token_macros::delim::Star };
974 [~] => { $crate::token_macros::delim::Tilde };
975 [_] => { $crate::token_macros::delim::Underscore };
976 ['`'] => { $crate::token_macros::delim::Backtick };
977
978 [>=] => { $crate::token_macros::double::GreaterThanEqual };
979 [<=] => { $crate::token_macros::double::LessThanEqual };
980 [*|] => { $crate::token_macros::double::StarPipe };
981 [::] => { $crate::token_macros::double::ColonColon };
982 [||] => { $crate::token_macros::double::PipePipe };
983 [==] => { $crate::token_macros::double::EqualEqual };
984 [~=] => { $crate::token_macros::double::TildeEqual };
985 [|=] => { $crate::token_macros::double::PipeEqual };
986 [^=] => { $crate::token_macros::double::CaretEqual };
987 ["$="] => { $crate::token_macros::double::DollarEqual };
988 [*=] => { $crate::token_macros::double::StarEqual };
989 [!=] => { $crate::token_macros::double::BangEqual };
990
991 [Dimension::$ident: ident] => { $crate::token_macros::dimension::$ident };
992
993 [!important] => { $crate::token_macros::double::BangImportant };
994
995 [$ident:ident] => { $crate::token_macros::$ident }
996}