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}
30
31macro_rules! define_kinds {
32 ($($(#[$meta:meta])* $ident:ident,)*) => {
33 $(
34 $(#[$meta])*
35 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
36 #[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
37 pub struct $ident($crate::Cursor);
38
39 impl $ident {
40 pub const fn dummy() -> Self {
41 Self($crate::Cursor::dummy($crate::Token::dummy($crate::Kind::$ident)))
42 }
43
44 pub fn associated_whitespace(&self) -> $crate::AssociatedWhitespaceRules {
45 self.0.token().associated_whitespace()
46 }
47
48 pub fn with_associated_whitespace(&self, rules: $crate::AssociatedWhitespaceRules) -> Self {
49 Self(self.0.with_associated_whitespace(rules))
50 }
51 }
52
53 impl $crate::ToCursors for $ident {
54 fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
55 s.append((*self).into());
56 }
57 }
58
59 impl<'a> $crate::Peek<'a> for $ident {
60 fn peek<I>(_: &$crate::Parser<'a, I>, c: $crate::Cursor) -> bool
61 where
62 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
63 {
64 c == $crate::Kind::$ident
65 }
66 }
67
68 impl<'a> $crate::Parse<'a> for $ident {
69 fn parse<I>(p: &mut $crate::Parser<'a, I>) -> $crate::Result<Self>
70 where
71 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
72 {
73 let c = p.next();
74 if Self::peek(p, c) { Ok(Self(c)) } else { Err($crate::Diagnostic::new(c, $crate::Diagnostic::unexpected))? }
75 }
76 }
77
78
79 impl From<$ident> for $crate::Cursor {
80 fn from(value: $ident) -> Self {
81 value.0.into()
82 }
83 }
84
85 impl From<$ident> for $crate::Token {
86 fn from(value: $ident) -> Self {
87 value.0.into()
88 }
89 }
90
91 impl $crate::ToSpan for $ident {
92 fn to_span(&self) -> $crate::Span {
93 self.0.to_span()
94 }
95 }
96 )*
97 };
98}
99
100macro_rules! define_kind_idents {
101 ($($(#[$meta:meta])* $ident:ident,)*) => {
102 $(
103 $(#[$meta])*
104 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
105 #[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
106 pub struct $ident($crate::Cursor);
107
108 impl $crate::ToCursors for $ident {
109 fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
110 s.append((*self).into());
111 }
112 }
113
114 impl<'a> $crate::Peek<'a> for $ident {
115 fn peek<I>(_: &$crate::Parser<'a, I>, c: $crate::Cursor) -> bool
116 where
117 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
118 {
119 c == $crate::Kind::$ident
120 }
121 }
122
123 impl<'a> $crate::Parse<'a> for $ident {
124 fn parse<I>(p: &mut $crate::Parser<'a, I>) -> $crate::Result<Self>
125 where
126 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
127 {
128 let c = p.next();
129 if Self::peek(p, c) { Ok(Self(c)) } else { Err($crate::Diagnostic::new(c, $crate::Diagnostic::unexpected))? }
130 }
131 }
132
133
134 impl From<$ident> for $crate::Kind {
135 fn from(value: $ident) -> Self {
136 value.0.into()
137 }
138 }
139
140 impl From<$ident> for $crate::Cursor {
141 fn from(value: $ident) -> Self {
142 value.0
143 }
144 }
145
146 impl From<$ident> for $crate::Token {
147 fn from(value: $ident) -> Self {
148 value.0.into()
149 }
150 }
151
152 impl $crate::ToSpan for $ident {
153 fn to_span(&self) -> $crate::Span {
154 self.0.to_span()
155 }
156 }
157
158 impl $ident {
159 pub fn is_dashed_ident(&self) -> bool {
161 self.0.token().is_dashed_ident()
162 }
163
164 pub const fn dummy() -> Self {
165 Self($crate::Cursor::dummy($crate::Token::dummy($crate::Kind::$ident)))
166 }
167 }
168 )*
169 };
170}
171
172#[macro_export]
187macro_rules! custom_delim {
188 ($(#[$meta:meta])* $ident:ident, $ch:literal) => {
189 $(#[$meta])*
190 #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
191 #[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
192 pub struct $ident($crate::T![Delim]);
193
194 impl $crate::ToCursors for $ident {
195 fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
196 s.append((*self).into());
197 }
198 }
199
200 impl<'a> $crate::Peek<'a> for $ident {
201 fn peek<I>(_: &$crate::Parser<'a, I>, c: $crate::Cursor) -> bool
202 where
203 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
204 {
205 c == $crate::Kind::Delim && c == $ch
206 }
207 }
208
209 impl<'a> $crate::Parse<'a> for $ident {
210 fn parse<I>(p: &mut $crate::Parser<'a, I>) -> $crate::Result<Self>
211 where
212 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
213 {
214 use $crate::Peek;
215 let delim = p.parse::<$crate::T![Delim]>()?;
216 if Self::peek(p, delim.into()) {
217 Ok(Self(delim))
218 } else {
219 Err($crate::Diagnostic::new(delim.into(), $crate::Diagnostic::unexpected))?
220 }
221 }
222 }
223
224
225
226 impl From<$ident> for $crate::Cursor {
227 fn from(value: $ident) -> Self {
228 value.0.into()
229 }
230 }
231
232 impl $crate::ToSpan for $ident {
233 fn to_span(&self) -> $crate::Span {
234 self.0.to_span()
235 }
236 }
237
238 impl PartialEq<char> for $ident {
239 fn eq(&self, other: &char) -> bool {
240 self.0 == *other
241 }
242 }
243 };
244}
245
246#[macro_export]
262macro_rules! custom_double_delim {
263 ($(#[$meta:meta])*$ident: ident, $first: literal, $second: literal) => {
264 $(#[$meta])*
265 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
266 #[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
267 pub struct $ident($crate::T![Delim], pub $crate::T![Delim]);
268
269 impl $ident {
270 pub const fn dummy() -> Self {
271 Self(<$crate::T![Delim]>::dummy(), <$crate::T![Delim]>::dummy())
272 }
273 }
274
275 impl<'a> $crate::Peek<'a> for $ident {
276 fn peek<I>(p: &$crate::Parser<'a, I>, c: $crate::Cursor) -> bool
277 where
278 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
279 {
280 c == $first && p.peek_n(2) == $second
281 }
282 }
283
284 impl<'a> $crate::Parse<'a> for $ident {
285 fn parse<I>(p: &mut $crate::Parser<'a, I>) -> $crate::Result<Self>
286 where
287 I: ::std::iter::Iterator<Item = $crate::Cursor> + ::std::clone::Clone,
288 {
289 let first = p.parse::<$crate::T![Delim]>()?;
290 if first != $first {
291 let c: Cursor = first.into();
292 Err($crate::Diagnostic::new(c, $crate::Diagnostic::expected_delim))?;
293 }
294 let skip = p.set_skip($crate::KindSet::NONE);
295 let second = p.parse::<$crate::T![Delim]>();
296 p.set_skip(skip);
297 let second = second?;
298 if second != $second {
299 let c:Cursor = second.into();
300 Err($crate::Diagnostic::new(c, $crate::Diagnostic::expected_delim))?;
301 }
302 Ok(Self(first, second))
303 }
304 }
305
306 impl<'a> $crate::ToCursors for $ident {
307 fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
308 s.append(self.0.into());
309 s.append(self.1.into());
310 }
311 }
312
313 impl $crate::ToSpan for $ident {
314 fn to_span(&self) -> $crate::Span {
315 self.0.to_span() + self.1.to_span()
316 }
317 }
318 };
319}
320
321define_kinds! {
322 Eof,
324
325 Comment,
327
328 CdcOrCdo,
330
331 BadString,
333
334 BadUrl,
336
337 Delim,
339
340 Colon,
342
343 Semicolon,
345
346 Comma,
348
349 LeftCurly,
351
352 RightCurly,
354
355 LeftSquare,
357
358 RightSquare,
360
361 LeftParen,
363
364 RightParen,
366}
367
368impl PartialEq<char> for Delim {
369 fn eq(&self, other: &char) -> bool {
370 self.0 == *other
371 }
372}
373
374define_kind_idents! {
375 Ident,
377
378 String,
380
381 Url,
383
384 Function,
386
387 AtKeyword,
389
390 Hash,
392}
393
394#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
397#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
398pub struct Whitespace(Cursor);
399cursor_wrapped!(Whitespace);
400
401impl<'a> Peek<'a> for Whitespace {
402 fn peek<I>(p: &Parser<'a, I>, _: Cursor) -> bool
403 where
404 I: Iterator<Item = Cursor> + Clone,
405 {
406 let c = p.peek_n_with_skip(1, KindSet::COMMENTS);
408 c == Kind::Whitespace
409 }
410}
411
412impl<'a> Parse<'a> for Whitespace {
413 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
414 where
415 I: Iterator<Item = Cursor> + Clone,
416 {
417 let skip = p.set_skip(KindSet::COMMENTS);
420 let c = p.next();
421 p.set_skip(skip);
422 if c != Kind::Whitespace {
423 Err(crate::Diagnostic::new(c, crate::Diagnostic::unexpected))?
424 }
425 Ok(Self(c))
426 }
427}
428
429#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
432#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
433pub struct DashedIdent(Ident);
434cursor_wrapped!(DashedIdent);
435
436impl<'a> Peek<'a> for DashedIdent {
437 fn peek<I>(_: &Parser<'a, I>, c: Cursor) -> bool
438 where
439 I: Iterator<Item = Cursor> + Clone,
440 {
441 c == Kind::Ident && c.token().is_dashed_ident()
442 }
443}
444
445impl<'a> Parse<'a> for DashedIdent {
446 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
447 where
448 I: Iterator<Item = Cursor> + Clone,
449 {
450 let c = p.next();
451 if Self::peek(p, c) {
452 Ok(Self(Ident(c)))
453 } else {
454 Err(crate::Diagnostic::new(c, crate::Diagnostic::unexpected))?
455 }
456 }
457}
458
459#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
461#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
462pub struct Dimension(Cursor);
463cursor_wrapped!(Dimension);
464
465impl PartialEq<f32> for Dimension {
466 fn eq(&self, other: &f32) -> bool {
467 self.0.token().value() == *other
468 }
469}
470
471impl<'a> Peek<'a> for Dimension {
472 fn peek<I>(_: &Parser<'a, I>, c: Cursor) -> bool
473 where
474 I: Iterator<Item = Cursor> + Clone,
475 {
476 c == Kind::Dimension
477 }
478}
479
480impl<'a> Parse<'a> for Dimension {
481 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
482 where
483 I: Iterator<Item = Cursor> + Clone,
484 {
485 let c = p.next();
486 if Self::peek(p, c) { Ok(Self(c)) } else { Err(crate::Diagnostic::new(c, crate::Diagnostic::unexpected))? }
487 }
488}
489
490impl From<Dimension> for f32 {
491 fn from(val: Dimension) -> Self {
492 val.0.token().value()
493 }
494}
495
496impl ToNumberValue for Dimension {
497 fn to_number_value(&self) -> Option<f32> {
498 Some(self.0.token().value())
499 }
500}
501
502impl Dimension {
503 pub fn value(&self) -> f32 {
505 self.0.token().value()
506 }
507}
508
509#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
511#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
512pub struct Number(Cursor);
513cursor_wrapped!(Number);
514
515impl Number {
516 pub const NUMBER_ZERO: Number = Number(Cursor::dummy(Token::NUMBER_ZERO));
517 pub const ZERO: Number = Number(Cursor::dummy(Token::NUMBER_ZERO));
518
519 pub fn value(&self) -> f32 {
521 self.0.token().value()
522 }
523
524 pub fn is_int(&self) -> bool {
525 self.0.token().is_int()
526 }
527
528 pub fn is_float(&self) -> bool {
529 self.0.token().is_float()
530 }
531
532 pub fn has_sign(&self) -> bool {
533 self.0.token().has_sign()
534 }
535}
536
537impl<'a> Peek<'a> for Number {
538 fn peek<I>(_: &Parser<'a, I>, c: Cursor) -> bool
539 where
540 I: Iterator<Item = Cursor> + Clone,
541 {
542 c == Kind::Number
543 }
544}
545
546impl<'a> Parse<'a> for Number {
547 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
548 where
549 I: Iterator<Item = Cursor> + Clone,
550 {
551 let c = p.next();
552 if Self::peek(p, c) { Ok(Self(c)) } else { Err(crate::Diagnostic::new(c, crate::Diagnostic::unexpected))? }
553 }
554}
555
556impl From<Number> for f32 {
557 fn from(value: Number) -> Self {
558 value.value()
559 }
560}
561
562impl From<Number> for i32 {
563 fn from(value: Number) -> Self {
564 value.value() as i32
565 }
566}
567
568impl PartialEq<f32> for Number {
569 fn eq(&self, other: &f32) -> bool {
570 self.value() == *other
571 }
572}
573
574impl ToNumberValue for Number {
575 fn to_number_value(&self) -> Option<f32> {
576 Some(self.value())
577 }
578}
579
580pub mod delim {
582 custom_delim! {
583 And, '&'
586 }
587 custom_delim! {
588 At, '@'
592 }
593 custom_delim! {
594 Caret, '^'
597 }
598 custom_delim! {
599 Dash, '-'
602 }
603 custom_delim! {
604 Dollar, '$'
607 }
608 custom_delim! {
609 Dot, '.'
612 }
613 custom_delim! {
614 Eq, '='
617 }
618 custom_delim! {
619 Gt, '>'
622 }
623 custom_delim! {
624 Hash, '#'
628 }
629 custom_delim! {
630 Lt, '<'
633 }
634 custom_delim! {
635 Bang, '!'
638 }
639 custom_delim! {
640 Or, '|'
643 }
644 custom_delim! {
645 Percent, '%'
648 }
649 custom_delim! {
650 Plus, '+'
653 }
654 custom_delim! {
655 Question, '?'
658 }
659 custom_delim! {
660 Slash, '/'
663 }
664 custom_delim! {
665 Star, '*'
668 }
669 custom_delim! {
670 Tilde, '~'
673 }
674 custom_delim! {
675 Underscore, '_'
678 }
679 custom_delim! {
680 Backtick, '`'
683 }
684}
685
686pub mod double {
690 use crate::{Cursor, CursorSink, Kind, KindSet, Parse, Parser, Peek, Result, Span, T, ToCursors, ToSpan};
691
692 custom_double_delim! {
693 GreaterThanEqual, '>', '='
697 }
698 custom_double_delim! {
699 LessThanEqual, '<', '='
703 }
704 custom_double_delim! {
705 StarPipe, '*', '|'
709 }
710 custom_double_delim! {
711 PipePipe, '|', '|'
715 }
716 custom_double_delim! {
717 EqualEqual, '=', '='
721 }
722 custom_double_delim! {
723 TildeEqual, '~', '='
727 }
728 custom_double_delim! {
729 PipeEqual, '|', '='
733 }
734 custom_double_delim! {
735 CaretEqual, '^', '='
739 }
740 custom_double_delim! {
741 DollarEqual, '$', '='
745 }
746 custom_double_delim! {
747 StarEqual, '*', '='
751 }
752
753 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
756 #[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
757 pub struct ColonColon(T![:], T![:]);
758
759 impl ColonColon {
760 pub const fn dummy() -> Self {
761 Self(<T![:]>::dummy(), <T![:]>::dummy())
762 }
763 }
764
765 impl<'a> Peek<'a> for ColonColon {
766 fn peek<I>(p: &Parser<'a, I>, c: Cursor) -> bool
767 where
768 I: Iterator<Item = Cursor> + Clone,
769 {
770 c == Kind::Colon && p.peek_n(2) == Kind::Colon
771 }
772 }
773
774 impl<'a> Parse<'a> for ColonColon {
775 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
776 where
777 I: Iterator<Item = Cursor> + Clone,
778 {
779 let first = p.parse::<T![:]>()?;
780 let skip = p.set_skip(KindSet::NONE);
781 let second = p.parse::<T![:]>();
782 p.set_skip(skip);
783 Ok(Self(first, second?))
784 }
785 }
786
787 impl ToCursors for ColonColon {
788 fn to_cursors(&self, s: &mut impl CursorSink) {
789 s.append(self.0.into());
790 s.append(self.1.into());
791 }
792 }
793
794 impl ToSpan for ColonColon {
795 fn to_span(&self) -> Span {
796 self.0.to_span() + self.1.to_span()
797 }
798 }
799}
800
801#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
803#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
804pub struct Any(Cursor);
805cursor_wrapped!(Any);
806
807impl<'a> Peek<'a> for Any {
808 fn peek<I>(_: &Parser<'a, I>, _: Cursor) -> bool
809 where
810 I: Iterator<Item = Cursor> + Clone,
811 {
812 true
813 }
814}
815
816impl<'a> Parse<'a> for Any {
817 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
818 where
819 I: Iterator<Item = Cursor> + Clone,
820 {
821 let c = p.next();
822 Ok(Self(c))
823 }
824}
825
826#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
829#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
830pub struct PairWiseStart(Cursor);
831cursor_wrapped!(PairWiseStart);
832
833impl PairWiseStart {
834 pub fn kind(&self) -> Kind {
835 self.0.token().kind()
836 }
837
838 pub fn end(&self) -> Kind {
839 match self.kind() {
840 Kind::LeftCurly => Kind::RightCurly,
841 Kind::LeftParen => Kind::RightParen,
842 Kind::LeftSquare => Kind::RightSquare,
843 k => k,
844 }
845 }
846}
847
848impl<'a> Peek<'a> for PairWiseStart {
849 const PEEK_KINDSET: KindSet = KindSet::new(&[Kind::LeftCurly, Kind::LeftSquare, Kind::LeftParen]);
850}
851
852impl<'a> Parse<'a> for PairWiseStart {
853 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
854 where
855 I: Iterator<Item = Cursor> + Clone,
856 {
857 let c = p.next();
858 if Self::peek(p, c) { Ok(Self(c)) } else { Err(crate::Diagnostic::new(c, crate::Diagnostic::unexpected))? }
859 }
860}
861
862#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
865#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
866pub struct PairWiseEnd(Cursor);
867cursor_wrapped!(PairWiseEnd);
868
869impl PairWiseEnd {
870 pub fn kind(&self) -> Kind {
871 self.0.token().kind()
872 }
873
874 pub fn start(&self) -> Kind {
875 match self.kind() {
876 Kind::RightCurly => Kind::LeftCurly,
877 Kind::RightParen => Kind::LeftParen,
878 Kind::RightSquare => Kind::LeftSquare,
879 k => k,
880 }
881 }
882}
883
884impl<'a> Peek<'a> for PairWiseEnd {
885 const PEEK_KINDSET: KindSet = KindSet::new(&[Kind::RightCurly, Kind::RightSquare, Kind::RightParen]);
886}
887
888impl<'a> Parse<'a> for PairWiseEnd {
889 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
890 where
891 I: Iterator<Item = Cursor> + Clone,
892 {
893 let c = p.next();
894 if Self::peek(p, c) { Ok(Self(c)) } else { Err(crate::Diagnostic::new(c, crate::Diagnostic::unexpected))? }
895 }
896}
897
898#[macro_export]
901macro_rules! T {
902 [:] => { $crate::token_macros::Colon };
903 [;] => { $crate::token_macros::Semicolon };
904 [,] => { $crate::token_macros::Comma };
905 ['{'] => { $crate::token_macros::LeftCurly };
906 ['}'] => { $crate::token_macros::RightCurly };
907 ['['] => { $crate::token_macros::LeftSquare };
908 [']'] => { $crate::token_macros::RightSquare };
909 ['('] => { $crate::token_macros::LeftParen };
910 [')'] => { $crate::token_macros::RightParen };
911 [' '] => { $crate::token_macros::Whitespace };
912
913 [&] => { $crate::token_macros::delim::And };
914 [@] => { $crate::token_macros::delim::At };
915 [^] => { $crate::token_macros::delim::Caret };
916 [-] => { $crate::token_macros::delim::Dash };
917 [$] => { $crate::token_macros::delim::Dollar };
918 [.] => { $crate::token_macros::delim::Dot };
919 [=] => { $crate::token_macros::delim::Eq };
920 [>] => { $crate::token_macros::delim::Gt };
921 [#] => { $crate::token_macros::delim::Hash };
922 [<] => { $crate::token_macros::delim::Lt };
923 [!] => { $crate::token_macros::delim::Bang };
924 [|] => { $crate::token_macros::delim::Or };
925 [%] => { $crate::token_macros::delim::Percent };
926 [+] => { $crate::token_macros::delim::Plus };
927 [?] => { $crate::token_macros::delim::Question };
928 [/] => { $crate::token_macros::delim::Slash };
929 [*] => { $crate::token_macros::delim::Star };
930 [~] => { $crate::token_macros::delim::Tilde };
931 [_] => { $crate::token_macros::delim::Underscore };
932 ['`'] => { $crate::token_macros::delim::Backtick };
933
934 [>=] => { $crate::token_macros::double::GreaterThanEqual };
935 [<=] => { $crate::token_macros::double::LessThanEqual };
936 [*|] => { $crate::token_macros::double::StarPipe };
937 [::] => { $crate::token_macros::double::ColonColon };
938 [||] => { $crate::token_macros::double::PipePipe };
939 [==] => { $crate::token_macros::double::EqualEqual };
940 [~=] => { $crate::token_macros::double::TildeEqual };
941 [|=] => { $crate::token_macros::double::PipeEqual };
942 [^=] => { $crate::token_macros::double::CaretEqual };
943 ["$="] => { $crate::token_macros::double::DollarEqual };
944 [*=] => { $crate::token_macros::double::StarEqual };
945
946 [Dimension::$ident: ident] => { $crate::token_macros::dimension::$ident };
947
948 [!important] => { $crate::token_macros::double::BangImportant };
949
950 [$ident:ident] => { $crate::token_macros::$ident }
951}