css_parse/
token_macros.rs

1use crate::{
2	Build, Cursor, CursorSink, DimensionUnit, Kind, KindSet, Parse, Parser, Peek, Result, Span, ToNumberValue, Token,
3	diagnostics,
4};
5
6macro_rules! cursor_wrapped {
7	($ident:ident) => {
8		impl $crate::ToCursors for $ident {
9			fn to_cursors(&self, s: &mut impl CursorSink) {
10				s.append((*self).into());
11			}
12		}
13
14		impl From<$ident> for $crate::Cursor {
15			fn from(value: $ident) -> Self {
16				value.0.into()
17			}
18		}
19
20		impl From<$ident> for $crate::Token {
21			fn from(value: $ident) -> Self {
22				value.0.into()
23			}
24		}
25
26		impl $crate::ToSpan for $ident {
27			fn to_span(&self) -> Span {
28				self.0.to_span()
29			}
30		}
31	};
32}
33
34macro_rules! define_kinds {
35	($($(#[$meta:meta])* $ident:ident,)*) => {
36		$(
37		$(#[$meta])*
38		#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
39		#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
40		pub struct $ident($crate::Cursor);
41
42		impl $ident {
43			pub const fn dummy() -> Self {
44				Self($crate::Cursor::dummy($crate::Token::dummy($crate::Kind::$ident)))
45			}
46
47			pub fn associated_whitespace(&self) -> $crate::AssociatedWhitespaceRules {
48				self.0.token().associated_whitespace()
49			}
50
51			pub fn with_associated_whitespace(&self, rules: $crate::AssociatedWhitespaceRules) -> Self {
52				Self(self.0.with_associated_whitespace(rules))
53			}
54		}
55
56		impl $crate::ToCursors for $ident {
57			fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
58				s.append((*self).into());
59			}
60		}
61
62		impl<'a> $crate::Peek<'a> for $ident {
63			fn peek(_: &$crate::Parser<'a>, c: $crate::Cursor) -> bool {
64				c == $crate::Kind::$ident
65			}
66		}
67
68		impl<'a> $crate::Build<'a> for $ident {
69			fn build(_: &$crate::Parser<'a>, c: $crate::Cursor) -> Self {
70				Self(c)
71			}
72		}
73
74		impl From<$ident> for $crate::Cursor {
75			fn from(value: $ident) -> Self {
76				value.0.into()
77			}
78		}
79
80		impl From<$ident> for $crate::Token {
81			fn from(value: $ident) -> Self {
82				value.0.into()
83			}
84		}
85
86		impl $crate::ToSpan for $ident {
87			fn to_span(&self) -> $crate::Span {
88				self.0.to_span()
89			}
90		}
91		)*
92	};
93}
94
95macro_rules! define_kind_idents {
96	($($(#[$meta:meta])* $ident:ident,)*) => {
97		$(
98		$(#[$meta])*
99		#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
100		#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
101		pub struct $ident($crate::Cursor);
102
103		impl $crate::ToCursors for $ident {
104			fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
105				s.append((*self).into());
106			}
107		}
108
109		impl<'a> $crate::Peek<'a> for $ident {
110			fn peek(_: &$crate::Parser<'a>, c: $crate::Cursor) -> bool {
111				c == $crate::Kind::$ident
112			}
113		}
114
115		impl<'a> $crate::Build<'a> for $ident {
116			fn build(_: &$crate::Parser<'a>, c: $crate::Cursor) -> Self {
117				Self(c)
118			}
119		}
120
121		impl From<$ident> for $crate::Kind {
122			fn from(value: $ident) -> Self {
123				value.0.into()
124			}
125		}
126
127		impl From<$ident> for $crate::Cursor {
128			fn from(value: $ident) -> Self {
129				value.0
130			}
131		}
132
133		impl From<$ident> for $crate::Token {
134			fn from(value: $ident) -> Self {
135				value.0.into()
136			}
137		}
138
139		impl $crate::ToSpan for $ident {
140			fn to_span(&self) -> $crate::Span {
141				self.0.to_span()
142			}
143		}
144
145		impl $ident {
146			/// Checks if the ident begins with two HYPHEN MINUS (`--`) characters.
147			pub fn is_dashed_ident(&self) -> bool {
148				self.0.token().is_dashed_ident()
149			}
150
151			pub const fn dummy() -> Self {
152				Self($crate::Cursor::dummy($crate::Token::dummy($crate::Kind::$ident)))
153			}
154		}
155		)*
156	};
157}
158
159/// A macro for defining a struct which captures a [Kind::Delim][Kind::Delim] with a specific character.
160///
161/// # Example
162///
163/// ```
164/// use css_parse::*;
165/// use bumpalo::Bump;
166/// custom_delim!{
167///   /// A £ character.
168///   PoundSterling, '£'
169/// }
170///
171/// assert_parse!(PoundSterling, "£");
172/// ```
173#[macro_export]
174macro_rules! custom_delim {
175	($(#[$meta:meta])* $ident:ident, $ch:literal) => {
176		$(#[$meta])*
177		#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
178		#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
179		pub struct $ident($crate::T![Delim]);
180
181		impl $crate::ToCursors for $ident {
182			fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
183				s.append((*self).into());
184			}
185		}
186
187		impl<'a> $crate::Peek<'a> for $ident {
188			fn peek(_: &$crate::Parser<'a>, c: $crate::Cursor) -> bool {
189				c == $crate::Kind::Delim && c == $ch
190			}
191		}
192
193		impl<'a> $crate::Build<'a> for $ident {
194			fn build(p: &$crate::Parser<'a>, c: $crate::Cursor) -> Self {
195				Self(<$crate::T![Delim]>::build(p, c))
196			}
197		}
198
199		impl From<$ident> for $crate::Cursor {
200			fn from(value: $ident) -> Self {
201				value.0.into()
202			}
203		}
204
205		impl $crate::ToSpan for $ident {
206			fn to_span(&self) -> $crate::Span {
207				self.0.to_span()
208			}
209		}
210
211		impl PartialEq<char> for $ident {
212			fn eq(&self, other: &char) -> bool {
213				self.0 == *other
214			}
215		}
216	};
217}
218
219#[doc(hidden)]
220#[macro_export]
221macro_rules! custom_dimension {
222	($(#[$meta:meta])*$ident: ident, $str: tt) => {
223		$(#[$meta])*
224		#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
225		#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
226		pub struct $ident($crate::Cursor);
227
228		impl $ident {
229			/// Returns the [f32] representation of the dimension's value.
230			pub fn value(&self) -> f32 {
231				self.0.token().value()
232			}
233
234			pub const fn dummy() -> Self {
235				Self($crate::Cursor::dummy($crate::Token::dummy($crate::Kind::Dimension)))
236			}
237		}
238
239		impl From<$ident> for $crate::Cursor {
240			fn from(value: $ident) -> Self {
241				value.0
242			}
243		}
244
245		impl $crate::ToCursors for $ident {
246			fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
247				s.append((*self).into());
248			}
249		}
250
251		impl $crate::ToSpan for $ident {
252			fn to_span(&self) -> $crate::Span {
253				self.0.to_span()
254			}
255		}
256
257		impl PartialEq<f32> for $ident {
258			fn eq(&self, other: &f32) -> bool {
259				self.value() == *other
260			}
261		}
262
263		impl $crate::ToNumberValue for $ident {
264			fn to_number_value(&self) -> Option<f32> {
265				Some(self.value())
266			}
267		}
268
269		impl<'a> $crate::Peek<'a> for $ident {
270			fn peek(p: &$crate::Parser<'a>, c: $crate::Cursor) -> bool {
271				c == $crate::Kind::Dimension
272					&& (c == $crate::DimensionUnit::$ident || p.eq_ignore_ascii_case(c, $str))
273			}
274		}
275
276		impl<'a> $crate::Build<'a> for $ident {
277			fn build(_: &$crate::Parser<'a>, c: $crate::Cursor) -> Self {
278				Self(c)
279			}
280		}
281
282		impl From<$ident> for i32 {
283			fn from(value: $ident) -> Self {
284				value.value() as i32
285			}
286		}
287
288		impl From<$ident> for f32 {
289			fn from(value: $ident) -> Self {
290				value.value()
291			}
292		}
293	};
294}
295
296/// A macro for defining a struct which captures two adjacent [Kind::Delim][Kind::Delim] tokens, each with a
297/// specific character.
298///
299/// # Example
300///
301/// ```
302/// use css_parse::*;
303/// use bumpalo::Bump;
304/// custom_double_delim!{
305///   /// Two % adjacent symbols
306///   DoublePercent, '%', '%'
307/// }
308///
309/// assert_parse!(DoublePercent, "%%");
310/// ```
311#[macro_export]
312macro_rules! custom_double_delim {
313	($(#[$meta:meta])*$ident: ident, $first: literal, $second: literal) => {
314		$(#[$meta])*
315		#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
316		#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
317		pub struct $ident(pub $crate::T![Delim], pub $crate::T![Delim]);
318
319		impl $ident {
320			pub const fn dummy() -> Self {
321				Self(<$crate::T![Delim]>::dummy(), <$crate::T![Delim]>::dummy())
322			}
323		}
324
325		impl<'a> $crate::Peek<'a> for $ident {
326			fn peek(p: &$crate::Parser<'a>, c: $crate::Cursor) -> bool {
327				c == $first && p.peek_n(2) == $second
328			}
329		}
330
331		impl<'a> $crate::Parse<'a> for $ident {
332			fn parse(p: &mut $crate::Parser<'a>) -> $crate::Result<Self> {
333				let first = p.parse::<$crate::T![Delim]>()?;
334				if first != $first {
335					let c: Cursor = first.into();
336					Err($crate::diagnostics::ExpectedDelim(c))?;
337				}
338				let skip = p.set_skip(KindSet::NONE);
339				let second = p.parse::<$crate::T![Delim]>();
340				p.set_skip(skip);
341				let second = second?;
342				if second != $second {
343					let c:Cursor = second.into();
344					Err($crate::diagnostics::ExpectedDelim(c))?;
345				}
346				Ok(Self(first, second))
347			}
348		}
349
350		impl<'a> $crate::ToCursors for $ident {
351			fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
352				s.append(self.0.into());
353				s.append(self.1.into());
354			}
355		}
356
357		impl $crate::ToSpan for $ident {
358			fn to_span(&self) -> $crate::Span {
359				self.0.to_span() + self.1.to_span()
360			}
361		}
362	};
363}
364
365/// A macro for defining an enum which captures a token with [Kind::Ident][Kind::Ident] that matches one of
366/// the variant names in the enum.
367///
368/// # Example
369///
370/// ```
371/// use css_parse::*;
372/// use bumpalo::Bump;
373/// keyword_set!(
374///   /// Some docs on this type...
375///   pub enum Keywords {
376///     Foo: "foo",
377///     Bar: "bar",
378///     Baz: "baz"
379///   }
380/// );
381///
382/// // Matches are case insensitive
383/// assert_parse!(Keywords, "FoO");
384///
385/// // The result will be one of the variants in the enum, matching the keyword.
386/// assert_parse!(Keywords, "baR");
387///
388/// // Words that do not match will fail to parse.
389/// assert_parse_error!(Keywords, "bing");
390///
391/// assert_parse_error!(Keywords, "oof");
392/// ```
393#[macro_export]
394macro_rules! keyword_set {
395	($(#[$meta:meta])* $vis:vis enum $name: ident { $( $variant: ident: $variant_str: tt$(,)?)+ }) => {
396		$(#[$meta])*
397		#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
398		#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
399		$vis enum $name {
400			$($variant($crate::token_macros::Ident)),+
401		}
402		impl<'a> $crate::Peek<'a> for $name {
403			fn peek(p: &$crate::Parser<'a>, c: $crate::Cursor) -> bool {
404				c == $crate::Kind::Ident && Self::MAP.get(&p.parse_str_lower(c)).is_some()
405			}
406		}
407		impl<'a> $crate::Build<'a> for $name {
408			fn build(p: &$crate::Parser<'a>, c: $crate::Cursor) -> Self {
409				use $crate::Peek;
410				debug_assert!(Self::peek(p, c));
411				let val = Self::MAP.get(&p.parse_str_lower(c)).unwrap();
412				let ident = $crate::token_macros::Ident::build(p, c);
413				match val {
414					$(Self::$variant(_) => Self::$variant(ident),)+
415				}
416			}
417		}
418		impl $name {
419			const MAP: phf::Map<&'static str, $name> = phf::phf_map! {
420					$($variant_str => $name::$variant($crate::token_macros::Ident::dummy())),+
421			};
422		}
423
424		impl From<$name> for $crate::Kind {
425			fn from(value: $name) -> Self {
426				match value {
427					$($name::$variant(t) => t.into(),)+
428				}
429			}
430		}
431
432		impl From<$name> for $crate::Token {
433			fn from(value: $name) -> Self {
434				match value {
435					$($name::$variant(t) => t.into(),)+
436				}
437			}
438		}
439
440		impl From<$name> for $crate::Cursor {
441			fn from(value: $name) -> Self {
442				match value {
443					$($name::$variant(t) => t.into(),)+
444				}
445			}
446		}
447
448		impl From<$name> for $crate::token_macros::Ident {
449			fn from(value: $name) -> Self {
450				match value {
451					$($name::$variant(t) => t,)+
452				}
453			}
454		}
455
456		impl $crate::ToCursors for $name {
457			fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
458				s.append((*self).into());
459			}
460		}
461
462		impl $crate::ToSpan for $name {
463			fn to_span(&self) -> $crate::Span {
464				match self {
465					$($name::$variant(t) => (t.to_span()),)+
466				}
467			}
468		}
469	};
470
471	($(#[$meta:meta])* $vis:vis struct $name: ident $str: tt) => {
472		$(#[$meta])*
473		#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
474		#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
475		$vis struct $name($crate::T![Ident]);
476
477		impl $crate::ToCursors for $name {
478			fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
479				s.append((*self).into());
480			}
481		}
482
483		impl<'a> $crate::Peek<'a> for $name {
484			fn peek(p: &$crate::Parser<'a>, c: $crate::Cursor) -> bool {
485				<$crate::T![Ident]>::peek(p, c) && p.eq_ignore_ascii_case(c, $str)
486			}
487		}
488
489		impl<'a> $crate::Build<'a> for $name {
490			fn build(p: &$crate::Parser<'a>, c: $crate::Cursor) -> Self {
491				use $crate::Peek;
492				debug_assert!(Self::peek(p, c));
493				Self(<$crate::T![Ident]>::build(p, c))
494			}
495		}
496
497		impl From<$name> for $crate::Cursor {
498			fn from(value: $name) -> Self {
499				value.0.into()
500			}
501		}
502
503		impl From<$name> for $crate::Token {
504			fn from(value: $name) -> Self {
505				value.0.into()
506			}
507		}
508
509		impl $crate::ToSpan for $name {
510			fn to_span(&self) -> $crate::Span {
511				self.0.to_span()
512			}
513		}
514
515		impl<'a> From<$name> for $crate::token_macros::Ident {
516			fn from(value: $name) -> Self {
517				value.0
518			}
519		}
520	};
521}
522
523/// A macro for defining an enum which captures a token with [Kind::Function][Kind::Function] that matches
524/// one of the variant names in the enum.
525///
526/// # Example
527///
528/// ```
529/// use css_parse::*;
530/// use bumpalo::Bump;
531/// function_set!(
532///   /// Some docs on this type...
533///   pub enum Functions {
534///     Foo: "foo",
535///     Bar: "bar",
536///     Baz: "baz"
537///   }
538/// );
539///
540/// // Matches are case insensitive
541/// assert_parse!(Functions, "FoO(");
542///
543/// // The result will be one of the variants in the enum, matching the keyword.
544/// assert_parse!(Functions, "baR(");
545///
546/// // Words that do not match will fail to parse.
547/// assert_parse_error!(Functions, "bing(");
548///
549/// assert_parse_error!(Functions, "oof(");
550/// ```
551#[macro_export]
552macro_rules! function_set {
553	($(#[$meta:meta])* $vis:vis enum $name: ident { $( $variant: ident: $variant_str: tt$(,)?)+ }) => {
554		$(#[$meta])*
555		#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
556		#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
557		$vis enum $name {
558			$($variant($crate::token_macros::Function)),+
559		}
560		impl<'a> $crate::Peek<'a> for $name {
561			fn peek(p: &$crate::Parser<'a>, c: $crate::Cursor) -> bool {
562				c == $crate::Kind::Function && Self::MAP.get(p.parse_str_lower(c)).is_some()
563			}
564		}
565		impl<'a> $crate::Build<'a> for $name {
566			fn build(p: &$crate::Parser<'a>, c: $crate::Cursor) -> Self {
567				use $crate::Peek;
568				debug_assert!(Self::peek(p, c));
569				let val = Self::MAP.get(p.parse_str_lower(c)).unwrap();
570				let function = $crate::token_macros::Function::build(p, c);
571				match val {
572					$(Self::$variant(_) => Self::$variant(function),)+
573				}
574			}
575		}
576		impl $name {
577			const MAP: phf::Map<&'static str, $name> = phf::phf_map! {
578				$($variant_str => $name::$variant($crate::token_macros::Function::dummy())),+
579			};
580		}
581
582		impl From<$name> for $crate::Token {
583			fn from(value: $name) -> Self {
584				match value {
585					$($name::$variant(t) => t.into(),)+
586				}
587			}
588		}
589
590		impl From<$name> for $crate::Cursor {
591			fn from(value: $name) -> Self {
592				match value {
593					$($name::$variant(t) => t.into(),)+
594				}
595			}
596		}
597
598		impl $crate::ToCursors for $name {
599			fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
600				s.append((*self).into());
601			}
602		}
603
604		impl $crate::ToSpan for $name {
605			fn to_span(&self) -> $crate::Span {
606				match self {
607					$($name::$variant(t) => (t.to_span()),)+
608				}
609			}
610		}
611
612		impl<'a> From<$name> for $crate::token_macros::Function {
613			fn from(value: $name) -> Self {
614				match value {
615					$($name::$variant(t) => t,)+
616				}
617			}
618		}
619	};
620
621	($(#[$meta:meta])* $vis:vis struct $name: ident $str: tt) => {
622		$(#[$meta])*
623		#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
624		#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
625		$vis struct $name($crate::T![Function]);
626
627		impl $crate::ToCursors for $name {
628			fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
629				s.append((*self).into());
630			}
631		}
632
633		impl<'a> $crate::Peek<'a> for $name {
634			fn peek(p: &$crate::Parser<'a>, c: $crate::Cursor) -> bool {
635				<$crate::T![Function]>::peek(p, c) && p.eq_ignore_ascii_case(c, $str)
636			}
637		}
638
639		impl<'a> $crate::Build<'a> for $name {
640			fn build(p: &$crate::Parser<'a>, c: $crate::Cursor) -> Self {
641				use $crate::Peek;
642				debug_assert!(Self::peek(p, c));
643				Self(<$crate::T![Function]>::build(p, c))
644			}
645		}
646
647		impl From<$name> for $crate::Cursor {
648			fn from(value: $name) -> Self {
649				value.0.into()
650			}
651		}
652
653		impl From<$name> for $crate::Token {
654			fn from(value: $name) -> Self {
655				value.0.into()
656			}
657		}
658
659		impl $crate::ToSpan for $name {
660			fn to_span(&self) -> $crate::Span {
661				self.0.to_span()
662			}
663		}
664
665		impl<'a> From<$name> for $crate::token_macros::Function {
666			fn from(value: $name) -> Self {
667				value.0
668			}
669		}
670	};
671}
672
673/// A macro for defining an enum which captures a token with [Kind::AtKeyword][Kind::AtKeyword] that matches one of
674/// the variant names in the enum.
675///
676/// # Example
677///
678/// ```
679/// use css_parse::*;
680/// use bumpalo::Bump;
681/// atkeyword_set!(
682///   /// Some docs on this type...
683///   pub enum Keywords {
684///     Foo: "foo",
685///     Bar: "bar",
686///     Baz: "baz"
687///   }
688/// );
689///
690/// // Matches are case insensitive
691/// assert_parse!(Keywords, "@FoO");
692///
693/// // The result will be one of the variants in the enum, matching the keyword.
694/// assert_parse!(Keywords, "@baR");
695///
696/// // Words that do not match will fail to parse.
697/// assert_parse_error!(Keywords, "@bing");
698///
699/// assert_parse_error!(Keywords, "@oof");
700/// ```
701#[macro_export]
702macro_rules! atkeyword_set {
703	($(#[$meta:meta])* $vis:vis enum $name: ident { $( $variant: ident: $variant_str: tt$(,)?)+ }) => {
704		$(#[$meta])*
705		#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
706		#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
707		$vis enum $name {
708			$($variant($crate::token_macros::AtKeyword)),+
709		}
710		impl<'a> $crate::Peek<'a> for $name {
711			fn peek(p: &$crate::Parser<'a>, c: $crate::Cursor) -> bool {
712				c == $crate::Kind::AtKeyword && Self::MAP.get(&p.parse_str_lower(c)).is_some()
713			}
714		}
715		impl<'a> $crate::Build<'a> for $name {
716			fn build(p: &$crate::Parser<'a>, c: $crate::Cursor) -> Self {
717				use $crate::Peek;
718				debug_assert!(Self::peek(p, c));
719				let val = Self::MAP.get(&p.parse_str_lower(c)).unwrap();
720				let at_keyword = $crate::token_macros::AtKeyword::build(p, c);
721				match val {
722					$(Self::$variant(_) => Self::$variant(at_keyword),)+
723				}
724			}
725		}
726		impl $name {
727			const MAP: phf::Map<&'static str, $name> = phf::phf_map! {
728					$($variant_str => $name::$variant($crate::token_macros::AtKeyword::dummy())),+
729			};
730		}
731
732		impl From<$name> for $crate::Token {
733			fn from(value: $name) -> Self {
734				match value {
735					$($name::$variant(t) => t.into(),)+
736				}
737			}
738		}
739
740		impl From<$name> for $crate::Cursor {
741			fn from(value: $name) -> Self {
742				match value {
743					$($name::$variant(t) => t.into(),)+
744				}
745			}
746		}
747
748		impl $crate::ToCursors for $name {
749			fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
750				s.append((*self).into());
751			}
752		}
753
754		impl $crate::ToSpan for $name {
755			fn to_span(&self) -> $crate::Span {
756				match self {
757					$($name::$variant(t) => (t.to_span()),)+
758				}
759			}
760		}
761
762		impl<'a> From<$name> for $crate::token_macros::AtKeyword {
763			fn from(value: $name) -> Self {
764				match value {
765					$($name::$variant(t) => t,)+
766				}
767			}
768		}
769	};
770	($(#[$meta:meta])* $vis:vis struct $name: ident $str: tt) => {
771		$(#[$meta])*
772		#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
773		#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
774		$vis struct $name($crate::T![AtKeyword]);
775
776		impl $crate::ToCursors for $name {
777			fn to_cursors(&self, s: &mut impl $crate::CursorSink) {
778				s.append((*self).into());
779			}
780		}
781
782		impl<'a> $crate::Peek<'a> for $name {
783			fn peek(p: &$crate::Parser<'a>, c: $crate::Cursor) -> bool {
784				<$crate::T![AtKeyword]>::peek(p, c) && p.eq_ignore_ascii_case(c, $str)
785			}
786		}
787
788		impl<'a> $crate::Build<'a> for $name {
789			fn build(p: &$crate::Parser<'a>, c: $crate::Cursor) -> Self {
790				use $crate::Peek;
791				debug_assert!(Self::peek(p, c));
792				Self(<$crate::T![AtKeyword]>::build(p, c))
793			}
794		}
795
796		impl From<$name> for $crate::Cursor {
797			fn from(value: $name) -> Self {
798				value.0.into()
799			}
800		}
801
802		impl From<$name> for $crate::Token {
803			fn from(value: $name) -> Self {
804				value.0.into()
805			}
806		}
807
808		impl $crate::ToSpan for $name {
809			fn to_span(&self) -> $crate::Span {
810				self.0.to_span()
811			}
812		}
813
814		impl<'a> From<$name> for $crate::token_macros::AtKeyword {
815			fn from(value: $name) -> Self {
816				value.0
817			}
818		}
819	};
820}
821
822define_kinds! {
823	/// Represents a token with [Kind::Eof][Kind::Eof]. Use [T![Eof]][crate::T] to refer to this.
824	Eof,
825
826	/// Represents a token with [Kind::Comment][Kind::Comment]. Use [T![Comment]][crate::T] to refer to this.
827	Comment,
828
829	/// Represents a token with [Kind::CdcOrCdo][Kind::CdcOrCdo]. Use [T![CdcOrCdo]][crate::T] to refer to this.
830	CdcOrCdo,
831
832	/// Represents a token with [Kind::BadString][Kind::BadString]. Use [T![BadString]][crate::T] to refer to this.
833	BadString,
834
835	/// Represents a token with [Kind::BadUrl][Kind::BadUrl]. Use [T![BadUrl]][crate::T] to refer to this.[
836	BadUrl,
837
838	/// Represents a token with [Kind::Delim][Kind::Delim], can be any single character. Use [T![Delim]][crate::T] to refer to this.
839	Delim,
840
841	/// Represents a token with [Kind::Colon][Kind::Colon] - a `:` character. Use [T![:]][crate::T] to refer to this.
842	Colon,
843
844	/// Represents a token with [Kind::Semicolon][Kind::Semicolon] - a `;` character. Use [T![;]][crate::T] to refer to this.
845	Semicolon,
846
847	/// Represents a token with [Kind::Comma][Kind::Comma] - a `,` character. Use [T![,]][crate::T] to refer to this.
848	Comma,
849
850	/// Represents a token with [Kind::LeftCurly][Kind::LeftCurly] - a `{` character. Use [T!['{']][crate::T] to refer to this.
851	LeftCurly,
852
853	/// Represents a token with [Kind::LeftCurly][Kind::LeftCurly] - a `}` character. Use [T!['}']][crate::T] to refer to this.
854	RightCurly,
855
856	/// Represents a token with [Kind::LeftSquare][Kind::LeftSquare] - a `[` character. Use [T!['[']][crate::T] to refer to this.
857	LeftSquare,
858
859	/// Represents a token with [Kind::RightSquare][Kind::RightSquare] - a `]` character. Use [T![']']][crate::T] to refer to this.
860	RightSquare,
861
862	/// Represents a token with [Kind::LeftParen][Kind::LeftParen] - a `(` character. Use [T!['(']][crate::T] to refer to this.
863	LeftParen,
864
865	/// Represents a token with [Kind::RightParen][Kind::RightParen] - a `(` character. Use [T![')']][crate::T] to refer to this.
866	RightParen,
867}
868
869impl PartialEq<char> for Delim {
870	fn eq(&self, other: &char) -> bool {
871		self.0 == *other
872	}
873}
874
875define_kind_idents! {
876	/// Represents a token with [Kind::Ident][Kind::Ident]. Use [T![Ident]][crate::T] to refer to this.
877	Ident,
878
879	/// Represents a token with [Kind::String][Kind::String]. Use [T![String]][crate::T] to refer to this.
880	String,
881
882	/// Represents a token with [Kind::Url][Kind::Url]. Use [T![Url]][crate::T] to refer to this.
883	Url,
884
885	/// Represents a token with [Kind::Function][Kind::Function]. Use [T![Function]][crate::T] to refer to this.
886	Function,
887
888	/// Represents a token with [Kind::AtKeyword][Kind::AtKeyword]. Use [T![AtKeyword]][crate::T] to refer to this.
889	AtKeyword,
890
891	/// Represents a token with [Kind::Hash][Kind::Hash]. Use [T![Hash]][crate::T] to refer to this.
892	Hash,
893}
894
895/// Represents a token with [Kind::Whitespace]. Use [T![Whitespace]][crate::T] to refer to
896/// this.
897#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
898#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
899pub struct Whitespace(Cursor);
900cursor_wrapped!(Whitespace);
901
902impl<'a> Peek<'a> for Whitespace {
903	fn peek(p: &Parser<'a>, _: Cursor) -> bool {
904		// Whitespace needs to peek its own cursor because it was likely given one that skipped Whitespace.
905		let c = p.peek_next_including_whitespace();
906		c == Kind::Whitespace
907	}
908}
909
910impl<'a> Parse<'a> for Whitespace {
911	fn parse(p: &mut Parser<'a>) -> Result<Self> {
912		// Whitespace needs to implement parse so that it can change the skip-state to only ensuring Whitespace
913		// is not ignored.
914		let skip = p.set_skip(KindSet::COMMENTS);
915		let c = p.next();
916		p.set_skip(skip);
917		if c != Kind::Whitespace {
918			Err(diagnostics::Unexpected(c))?
919		}
920		Ok(Self(c))
921	}
922}
923
924/// Represents a token with [Kind::Ident] that also begins with two HYPHEN MINUS (`--`)
925/// characters. Use [T![DashedIdent]][crate::T] to refer to this.
926#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
927#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
928pub struct DashedIdent(Ident);
929cursor_wrapped!(DashedIdent);
930
931impl<'a> Peek<'a> for DashedIdent {
932	fn peek(_: &Parser<'a>, c: Cursor) -> bool {
933		c == Kind::Ident && c.token().is_dashed_ident()
934	}
935}
936
937impl<'a> Build<'a> for DashedIdent {
938	fn build(p: &Parser<'a>, c: Cursor) -> Self {
939		Self(Ident::build(p, c))
940	}
941}
942
943/// Represents a token with [Kind::Dimension]. Use [T![Dimension]][crate::T] to refer to this.
944#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
945#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
946pub struct Dimension(Cursor);
947cursor_wrapped!(Dimension);
948
949impl PartialEq<f32> for Dimension {
950	fn eq(&self, other: &f32) -> bool {
951		self.0.token().value() == *other
952	}
953}
954
955impl<'a> Peek<'a> for Dimension {
956	fn peek(_: &Parser<'a>, c: Cursor) -> bool {
957		c == Kind::Dimension
958	}
959}
960
961impl<'a> Build<'a> for Dimension {
962	fn build(_: &Parser<'a>, c: Cursor) -> Self {
963		Self(c)
964	}
965}
966
967impl From<Dimension> for f32 {
968	fn from(val: Dimension) -> Self {
969		val.0.token().value()
970	}
971}
972
973impl ToNumberValue for Dimension {
974	fn to_number_value(&self) -> Option<f32> {
975		Some(self.0.token().value())
976	}
977}
978
979impl From<Dimension> for (f32, DimensionUnit) {
980	fn from(val: Dimension) -> Self {
981		let value = val.0.token().value();
982		let unit = val.0.token().dimension_unit();
983		(value, unit)
984	}
985}
986
987impl Dimension {
988	/// Returns the [f32] representation of the dimension's value.
989	pub fn value(&self) -> f32 {
990		self.0.token().value()
991	}
992
993	/// Returns the [DimensionUnit].
994	///
995	/// If the dimension unit is custom (e.g. dashed), has escape characters, or is not a recognised CSS Dimension, this
996	/// will return [DimensionUnit::Unknown].
997	pub fn dimension_unit(&self) -> DimensionUnit {
998		self.0.token().dimension_unit()
999	}
1000}
1001
1002#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1003#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
1004pub struct DimensionIdent(Cursor, DimensionUnit);
1005cursor_wrapped!(DimensionIdent);
1006
1007impl<'a> Peek<'a> for DimensionIdent {
1008	fn peek(p: &Parser<'a>, c: Cursor) -> bool {
1009		Ident::peek(p, c) && (DimensionUnit::from(p.parse_str_lower(c)) != DimensionUnit::Unknown)
1010	}
1011}
1012
1013impl<'a> Build<'a> for DimensionIdent {
1014	fn build(p: &Parser<'a>, c: Cursor) -> Self {
1015		Self(c, DimensionUnit::from(p.parse_str_lower(c)))
1016	}
1017}
1018
1019/// Represents a token with [Kind::Number]. Use [T![Number]][crate::T] to refer to this.
1020#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1021#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
1022pub struct Number(Cursor);
1023cursor_wrapped!(Number);
1024
1025impl Number {
1026	pub const NUMBER_ZERO: Number = Number(Cursor::dummy(Token::NUMBER_ZERO));
1027	pub const ZERO: Number = Number(Cursor::dummy(Token::NUMBER_ZERO));
1028
1029	/// Returns the [f32] representation of the number's value.
1030	pub fn value(&self) -> f32 {
1031		self.0.token().value()
1032	}
1033
1034	pub fn is_int(&self) -> bool {
1035		self.0.token().is_int()
1036	}
1037
1038	pub fn is_float(&self) -> bool {
1039		self.0.token().is_float()
1040	}
1041
1042	pub fn has_sign(&self) -> bool {
1043		self.0.token().has_sign()
1044	}
1045}
1046
1047impl<'a> Peek<'a> for Number {
1048	fn peek(_: &Parser<'a>, c: Cursor) -> bool {
1049		c == Kind::Number
1050	}
1051}
1052
1053impl<'a> Build<'a> for Number {
1054	fn build(_: &Parser<'a>, c: Cursor) -> Self {
1055		Self(c)
1056	}
1057}
1058
1059impl From<Number> for f32 {
1060	fn from(value: Number) -> Self {
1061		value.value()
1062	}
1063}
1064
1065impl From<Number> for i32 {
1066	fn from(value: Number) -> Self {
1067		value.value() as i32
1068	}
1069}
1070
1071impl PartialEq<f32> for Number {
1072	fn eq(&self, other: &f32) -> bool {
1073		self.value() == *other
1074	}
1075}
1076
1077impl ToNumberValue for Number {
1078	fn to_number_value(&self) -> Option<f32> {
1079		Some(self.value())
1080	}
1081}
1082
1083/// Various [T!s][crate::T] representing a tokens with [Kind::Delim], but each represents a discrete character.
1084pub mod delim {
1085	custom_delim! {
1086		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `&`. Use [T![&]][crate::T] to
1087		/// refer to this.
1088		And, '&'
1089	}
1090	custom_delim! {
1091		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `@`. Use [T![@]][crate::T] to
1092		/// refer to this. Not to be conused with [T![AtKeyword]][crate::T] which represents a token with
1093		/// [Kind::AtKeyword][crate::Kind::AtKeyword].
1094		At, '@'
1095	}
1096	custom_delim! {
1097		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `^`. Use [T![^]][crate::T] to
1098		/// refer to this.
1099		Caret, '^'
1100	}
1101	custom_delim! {
1102		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `-`. Use [T![-]][crate::T] to
1103		/// refer to this.
1104		Dash, '-'
1105	}
1106	custom_delim! {
1107		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `$`. Use [T![$]][crate::T] to
1108		/// refer to this.
1109		Dollar, '$'
1110	}
1111	custom_delim! {
1112		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `.`. Use [T![.]][crate::T] to
1113		/// refer to this.
1114		Dot, '.'
1115	}
1116	custom_delim! {
1117		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `=`. Use [T![=]][crate::T] to
1118		/// refer to this.
1119		Eq, '='
1120	}
1121	custom_delim! {
1122		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `>`. Use [T![>]][crate::T] to
1123		/// refer to this.
1124		Gt, '>'
1125	}
1126	custom_delim! {
1127		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `#`. Use [T![#]][crate::T] to
1128		/// refer to this. Not to be conused with [T![Hash]][crate::T] which represents a token with
1129		/// [Kind::Hash][crate::Kind::Hash].
1130		Hash, '#'
1131	}
1132	custom_delim! {
1133		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `<`. Use [T![<]][crate::T] to
1134		/// refer to this.
1135		Lt, '<'
1136	}
1137	custom_delim! {
1138		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `!`. Use [T![!]][crate::T] to
1139		/// refer to this.
1140		Bang, '!'
1141	}
1142	custom_delim! {
1143		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `|`. Use [T![|]][crate::T] to
1144		/// refer to this.
1145		Or, '|'
1146	}
1147	custom_delim! {
1148		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `%`. Use [T![%]][crate::T] to
1149		/// refer to this.
1150		Percent, '%'
1151	}
1152	custom_delim! {
1153		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `+`. Use [T![+]][crate::T] to
1154		/// refer to this.
1155		Plus, '+'
1156	}
1157	custom_delim! {
1158		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `?`. Use [T![?]][crate::T] to
1159		/// refer to this.
1160		Question, '?'
1161	}
1162	custom_delim! {
1163		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `/`. Use [T![/]][crate::T] to
1164		/// refer to this.
1165		Slash, '/'
1166	}
1167	custom_delim! {
1168		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `*`. Use [T![*]][crate::T] to
1169		/// refer to this.
1170		Star, '*'
1171	}
1172	custom_delim! {
1173		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `~`. Use [T![~]][crate::T] to
1174		/// refer to this.
1175		Tilde, '~'
1176	}
1177	custom_delim! {
1178		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char `_`. Use [T![_]][crate::T] to
1179		/// refer to this.
1180		Underscore, '_'
1181	}
1182	custom_delim! {
1183		/// Represents a token with [Kind::Delim][crate::Kind::Delim] that has the char ```. Use [T!['`']][crate::T] to
1184		/// refer to this.
1185		Backtick, '`'
1186	}
1187}
1188
1189/// Various [T!s][crate::T] representing two consecutive tokens that cannot be separated by any other tokens. These are
1190/// convenient as it can be tricky to parse two consecutive tokens given the default behaviour of the parser is to skip
1191/// whitespace and comments.
1192pub mod double {
1193	use crate::{Cursor, CursorSink, Kind, KindSet, Parse, Parser, Peek, Result, Span, T, ToCursors, ToSpan};
1194
1195	custom_double_delim! {
1196		/// Represents a two consecutive tokens with [Kind::Delim][crate::Kind::Delim] that cannot be separated by any
1197		/// other token. The first token has the char `>` while the second has the char `=`, representing `>=`. Use
1198		/// [T![>=]][crate::T] to refer to this.
1199		GreaterThanEqual, '>', '='
1200	}
1201	custom_double_delim! {
1202		/// Represents a two consecutive tokens with [Kind::Delim][crate::Kind::Delim] that cannot be separated by any
1203		/// other token. The first token has the char `<` while the second has the char `=`, representing `<=`. Use
1204		/// [T![<=]][crate::T] to refer to this.
1205		LessThanEqual, '<', '='
1206	}
1207	custom_double_delim! {
1208		/// Represents a two consecutive tokens with [Kind::Delim][crate::Kind::Delim] that cannot be separated by any
1209		/// other token. The first token has the char `*` while the second has the char `|`, representing `*|`. Use
1210		/// [T![*|]][crate::T] to refer to this.
1211		StarPipe, '*', '|'
1212	}
1213	custom_double_delim! {
1214		/// Represents a two consecutive tokens with [Kind::Delim][crate::Kind::Delim] that cannot be separated by any
1215		/// other token. The first token has the char `|` while the second has the char `|`, representing `||`. Use
1216		/// [T![||]][crate::T] to refer to this.
1217		PipePipe, '|', '|'
1218	}
1219	custom_double_delim! {
1220		/// Represents a two consecutive tokens with [Kind::Delim][crate::Kind::Delim] that cannot be separated by any
1221		/// other token. The first token has the char `=` while the second has the char `=`, representing `==`. Use
1222		/// [T![==]][crate::T] to refer to this.
1223		EqualEqual, '=', '='
1224	}
1225	custom_double_delim! {
1226		/// Represents a two consecutive tokens with [Kind::Delim][crate::Kind::Delim] that cannot be separated by any
1227		/// other token. The first token has the char `~` while the second has the char `=`, representing `~=`. Use
1228		/// [T![~=]][crate::T] to refer to this.
1229		TildeEqual, '~', '='
1230	}
1231	custom_double_delim! {
1232		/// Represents a two consecutive tokens with [Kind::Delim][crate::Kind::Delim] that cannot be separated by any
1233		/// other token. The first token has the char `|` while the second has the char `=`, representing `|=`. Use
1234		/// [T![|=]][crate::T] to refer to this.
1235		PipeEqual, '|', '='
1236	}
1237	custom_double_delim! {
1238		/// Represents a two consecutive tokens with [Kind::Delim][crate::Kind::Delim] that cannot be separated by any
1239		/// other token. The first token has the char `^` while the second has the char `=`, representing `^=`. Use
1240		/// [T![\^=]][crate::T] to refer to this.
1241		CaretEqual, '^', '='
1242	}
1243	custom_double_delim! {
1244		/// Represents a two consecutive tokens with [Kind::Delim][crate::Kind::Delim] that cannot be separated by any
1245		/// other token. The first token has the char `$` while the second has the char `=`, representing `$=`. Use
1246		/// [T![$=]][crate::T] to refer to this.
1247		DollarEqual, '$', '='
1248	}
1249	custom_double_delim! {
1250		/// Represents a two consecutive tokens with [Kind::Delim][crate::Kind::Delim] that cannot be separated by any
1251		/// other token. The first token has the char `*` while the second has the char `=`, representing `*=`. Use
1252		/// [T![*=]][crate::T] to refer to this.
1253		StarEqual, '*', '='
1254	}
1255
1256	/// Represents a two consecutive tokens with [Kind::Colon] that cannot be separated by any other token, representing
1257	/// `::`. Use [T![::]][crate::T] to refer to this.
1258	#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1259	#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
1260	pub struct ColonColon(T![:], T![:]);
1261
1262	impl ColonColon {
1263		pub const fn dummy() -> Self {
1264			Self(<T![:]>::dummy(), <T![:]>::dummy())
1265		}
1266	}
1267
1268	impl<'a> Peek<'a> for ColonColon {
1269		fn peek(p: &Parser<'a>, c: Cursor) -> bool {
1270			c == Kind::Colon && p.peek_n(2) == Kind::Colon
1271		}
1272	}
1273
1274	impl<'a> Parse<'a> for ColonColon {
1275		fn parse(p: &mut Parser<'a>) -> Result<Self> {
1276			let first = p.parse::<T![:]>()?;
1277			let skip = p.set_skip(KindSet::NONE);
1278			let second = p.parse::<T![:]>();
1279			p.set_skip(skip);
1280			Ok(Self(first, second?))
1281		}
1282	}
1283
1284	impl ToCursors for ColonColon {
1285		fn to_cursors(&self, s: &mut impl CursorSink) {
1286			s.append(self.0.into());
1287			s.append(self.1.into());
1288		}
1289	}
1290
1291	impl ToSpan for ColonColon {
1292		fn to_span(&self) -> Span {
1293			self.0.to_span() + self.1.to_span()
1294		}
1295	}
1296}
1297
1298/// Dimension specific [T!s][crate::T]. These are all [Kind::Dimension], but each represents
1299/// a discrete dimension unit.
1300pub mod dimension {
1301	custom_dimension! {
1302		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `cap`. Use
1303		/// [T![Dimension::Cap]][crate::T] to refer to this.
1304		Cap, "cap"
1305	}
1306	custom_dimension! {
1307		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `ch`. Use
1308		/// [T![Dimension::Ch]][crate::T] to refer to this.
1309		Ch, "ch"
1310	}
1311	custom_dimension! {
1312		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `cm`. Use
1313		/// [T![Dimension::Cm]][crate::T] to refer to this.
1314		Cm, "cm"
1315	}
1316	custom_dimension! {
1317		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `cqb`. Use
1318		/// [T![Dimension::Cqb]][crate::T] to refer to this.
1319		Cqb, "cqb"
1320	}
1321	custom_dimension! {
1322		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `cqh`. Use
1323		/// [T![Dimension::Cqh]][crate::T] to refer to this.
1324		Cqh, "cqh"
1325	}
1326	custom_dimension! {
1327		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `cqi`. Use
1328		/// [T![Dimension::Cqi]][crate::T] to refer to this.
1329		Cqi, "cqi"
1330	}
1331	custom_dimension! {
1332		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `cqmax`. Use
1333		/// [T![Dimension::Cqmax]][crate::T] to refer to this.
1334		Cqmax, "cqmax"
1335	}
1336	custom_dimension! {
1337		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `cqmin`. Use
1338		/// [T![Dimension::Cqmin]][crate::T] to refer to this.
1339		Cqmin, "cqmin"
1340	}
1341	custom_dimension! {
1342		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `cqw`. Use
1343		/// [T![Dimension::Cqw]][crate::T] to refer to this.
1344		Cqw, "cqw"
1345	}
1346	custom_dimension! {
1347		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `db`. Use
1348		/// [T![Dimension::Db]][crate::T] to refer to this.
1349		Db, "db"
1350	}
1351	custom_dimension! {
1352		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `deg`. Use
1353		/// [T![Dimension::Deg]][crate::T] to refer to this.
1354		Deg, "deg"
1355	}
1356	custom_dimension! {
1357		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `dpcm`. Use
1358		/// [T![Dimension::Dpcm]][crate::T] to refer to this.
1359		Dpcm, "dpcm"
1360	}
1361	custom_dimension! {
1362		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `dpi`. Use
1363		/// [T![Dimension::Dpi]][crate::T] to refer to this.
1364		Dpi, "dpi"
1365	}
1366	custom_dimension! {
1367		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `dppx`. Use
1368		/// [T![Dimension::Dppx]][crate::T] to refer to this.
1369		Dppx, "dppx"
1370	}
1371	custom_dimension! {
1372		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `dvb`. Use
1373		/// [T![Dimension::Dvb]][crate::T] to refer to this.
1374		Dvb, "dvb"
1375	}
1376	custom_dimension! {
1377		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `dvh`. Use
1378		/// [T![Dimension::Dvh]][crate::T] to refer to this.
1379		Dvh, "dvh"
1380	}
1381	custom_dimension! {
1382		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `dvi`. Use
1383		/// [T![Dimension::Dvi]][crate::T] to refer to this.
1384		Dvi, "dvi"
1385	}
1386	custom_dimension! {
1387		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `dvmax`. Use
1388		/// [T![Dimension::Dvmax]][crate::T] to refer to this.
1389		Dvmax, "dvmax"
1390	}
1391	custom_dimension! {
1392		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `dvmin`. Use
1393		/// [T![Dimension::Dvmin]][crate::T] to refer to this.
1394		Dvmin, "dvmin"
1395	}
1396	custom_dimension! {
1397		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `dvw`. Use
1398		/// [T![Dimension::Dvw]][crate::T] to refer to this.
1399		Dvw, "dvw"
1400	}
1401	custom_dimension! {
1402		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `em`. Use
1403		/// [T![Dimension::Em]][crate::T] to refer to this.
1404		Em, "em"
1405	}
1406	custom_dimension! {
1407		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `ex`. Use
1408		/// [T![Dimension::Ex]][crate::T] to refer to this.
1409		Ex, "ex"
1410	}
1411	custom_dimension! {
1412		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `fr`. Use
1413		/// [T![Dimension::Fr]][crate::T] to refer to this.
1414		Fr, "fr"
1415	}
1416	custom_dimension! {
1417		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `grad`. Use
1418		/// [T![Dimension::Grad]][crate::T] to refer to this.
1419		Grad, "grad"
1420	}
1421	custom_dimension! {
1422		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `hz`. Use
1423		/// [T![Dimension::Hz]][crate::T] to refer to this.
1424		Hz, "hz"
1425	}
1426	custom_dimension! {
1427		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `ic`. Use
1428		/// [T![Dimension::Ic]][crate::T] to refer to this.
1429		Ic, "ic"
1430	}
1431	custom_dimension! {
1432		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `in`. Use
1433		/// [T![Dimension::In]][crate::T] to refer to this.
1434		In, "in"
1435	}
1436	custom_dimension! {
1437		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `khz`. Use
1438		/// [T![Dimension::Khz]][crate::T] to refer to this.
1439		Khz, "khz"
1440	}
1441	custom_dimension! {
1442		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `lh`. Use
1443		/// [T![Dimension::Lh]][crate::T] to refer to this.
1444		Lh, "lh"
1445	}
1446	custom_dimension! {
1447		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `lvb`. Use
1448		/// [T![Dimension::Lvb]][crate::T] to refer to this.
1449		Lvb, "lvb"
1450	}
1451	custom_dimension! {
1452		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `lvh`. Use
1453		/// [T![Dimension::Lvh]][crate::T] to refer to this.
1454		Lvh, "lvh"
1455	}
1456	custom_dimension! {
1457		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `lvi`. Use
1458		/// [T![Dimension::Lvi]][crate::T] to refer to this.
1459		Lvi, "lvi"
1460	}
1461	custom_dimension! {
1462		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `lvmax`. Use
1463		/// [T![Dimension::Lvmax]][crate::T] to refer to this.
1464		Lvmax, "lvmax"
1465	}
1466	custom_dimension! {
1467		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `lvmin`. Use
1468		/// [T![Dimension::Lvmin]][crate::T] to refer to this.
1469		Lvmin, "lvmin"
1470	}
1471	custom_dimension! {
1472		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `lvw`. Use
1473		/// [T![Dimension::Lvw]][crate::T] to refer to this.
1474		Lvw, "lvw"
1475	}
1476	custom_dimension! {
1477		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `mm`. Use
1478		/// [T![Dimension::Mm]][crate::T] to refer to this.
1479		Mm, "mm"
1480	}
1481	custom_dimension! {
1482		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `ms`. Use
1483		/// [T![Dimension::Ms]][crate::T] to refer to this.
1484		Ms, "ms"
1485	}
1486	custom_dimension! {
1487		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `pc`. Use
1488		/// [T![Dimension::Pc]][crate::T] to refer to this.
1489		Pc, "pc"
1490	}
1491	custom_dimension! {
1492		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `%`. Use
1493		/// [T![Dimension::%]][crate::T] to refer to this.
1494		Percent, "%"
1495	}
1496	custom_dimension! {
1497		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `pt`. Use
1498		/// [T![Dimension::Pt]][crate::T] to refer to this.
1499		Pt, "pt"
1500	}
1501	custom_dimension! {
1502		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `px`. Use
1503		/// [T![Dimension::Px]][crate::T] to refer to this.
1504		Px, "px"
1505	}
1506	custom_dimension! {
1507		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `q`. Use
1508		/// [T![Dimension::Q]][crate::T] to refer to this.
1509		Q, "q"
1510	}
1511	custom_dimension! {
1512		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `rad`. Use
1513		/// [T![Dimension::Rad]][crate::T] to refer to this.
1514		Rad, "rad"
1515	}
1516	custom_dimension! {
1517		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `rcap`. Use
1518		/// [T![Dimension::Rcap]][crate::T] to refer to this.
1519		Rcap, "rcap"
1520	}
1521	custom_dimension! {
1522		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `rch`. Use
1523		/// [T![Dimension::Rch]][crate::T] to refer to this.
1524		Rch, "rch"
1525	}
1526	custom_dimension! {
1527		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `rem`. Use
1528		/// [T![Dimension::Rem]][crate::T] to refer to this.
1529		Rem, "rem"
1530	}
1531	custom_dimension! {
1532		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `rex`. Use
1533		/// [T![Dimension::Rex]][crate::T] to refer to this.
1534		Rex, "rex"
1535	}
1536	custom_dimension! {
1537		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `ric`. Use
1538		/// [T![Dimension::Ric]][crate::T] to refer to this.
1539		Ric, "ric"
1540	}
1541	custom_dimension! {
1542		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `rlh`. Use
1543		/// [T![Dimension::Rlh]][crate::T] to refer to this.
1544		Rlh, "rlh"
1545	}
1546	custom_dimension! {
1547		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `s`. Use
1548		/// [T![Dimension::S]][crate::T] to refer to this.
1549		S, "s"
1550	}
1551	custom_dimension! {
1552		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `svb`. Use
1553		/// [T![Dimension::Svb]][crate::T] to refer to this.
1554		Svb, "svb"
1555	}
1556	custom_dimension! {
1557		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `svh`. Use
1558		/// [T![Dimension::Svh]][crate::T] to refer to this.
1559		Svh, "svh"
1560	}
1561	custom_dimension! {
1562		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `svi`. Use
1563		/// [T![Dimension::Svi]][crate::T] to refer to this.
1564		Svi, "svi"
1565	}
1566	custom_dimension! {
1567		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `svmax`. Use
1568		/// [T![Dimension::Svmax]][crate::T] to refer to this.
1569		Svmax, "svmax"
1570	}
1571	custom_dimension! {
1572		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `svmin`. Use
1573		/// [T![Dimension::Svmin]][crate::T] to refer to this.
1574		Svmin, "svmin"
1575	}
1576	custom_dimension! {
1577		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `svw`. Use
1578		/// [T![Dimension::Svw]][crate::T] to refer to this.
1579		Svw, "svw"
1580	}
1581	custom_dimension! {
1582		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `turn`. Use
1583		/// [T![Dimension::Turn]][crate::T] to refer to this.
1584		Turn, "turn"
1585	}
1586	custom_dimension! {
1587		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `vb`. Use
1588		/// [T![Dimension::Vb]][crate::T] to refer to this.
1589		Vb, "vb"
1590	}
1591	custom_dimension! {
1592		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `vh`. Use
1593		/// [T![Dimension::Vh]][crate::T] to refer to this.
1594		Vh, "vh"
1595	}
1596	custom_dimension! {
1597		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `vi`. Use
1598		/// [T![Dimension::Vi]][crate::T] to refer to this.
1599		Vi, "vi"
1600	}
1601	custom_dimension! {
1602		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `vmax`. Use
1603		/// [T![Dimension::Vmax]][crate::T] to refer to this.
1604		Vmax, "vmax"
1605	}
1606	custom_dimension! {
1607		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `vmin`. Use
1608		/// [T![Dimension::Vmin]][crate::T] to refer to this.
1609		Vmin, "vmin"
1610	}
1611	custom_dimension! {
1612		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `vw`. Use
1613		/// [T![Dimension::Vw]][crate::T] to refer to this.
1614		Vw, "vw"
1615	}
1616	custom_dimension! {
1617		/// Represents a token with [Kind::Dimension][crate::Kind::Dimension] where the dimension unit was `x`. Use
1618		/// [T![Dimension::X]][crate::T] to refer to this.
1619		X, "x"
1620	}
1621}
1622
1623/// Represents any possible single token. Use [T![Any]][crate::T] to refer to this.
1624#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1625#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
1626pub struct Any(Cursor);
1627cursor_wrapped!(Any);
1628
1629impl<'a> Peek<'a> for Any {
1630	fn peek(_: &Parser<'a>, _: Cursor) -> bool {
1631		true
1632	}
1633}
1634
1635impl<'a> Build<'a> for Any {
1636	fn build(_: &Parser<'a>, c: Cursor) -> Self {
1637		Self(c)
1638	}
1639}
1640
1641/// Represents a token with either [Kind::LeftCurly], [Kind::LeftParen] or [Kind::LeftSquare]. Use
1642/// [T![PairWiseStart]][crate::T] to refer to this.
1643#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1644#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
1645pub struct PairWiseStart(Cursor);
1646cursor_wrapped!(PairWiseStart);
1647
1648impl PairWiseStart {
1649	pub fn kind(&self) -> Kind {
1650		self.0.token().kind()
1651	}
1652
1653	pub fn end(&self) -> Kind {
1654		match self.kind() {
1655			Kind::LeftCurly => Kind::RightCurly,
1656			Kind::LeftParen => Kind::RightParen,
1657			Kind::LeftSquare => Kind::RightSquare,
1658			k => k,
1659		}
1660	}
1661}
1662
1663impl<'a> Peek<'a> for PairWiseStart {
1664	const PEEK_KINDSET: KindSet = KindSet::new(&[Kind::LeftCurly, Kind::LeftSquare, Kind::LeftParen]);
1665}
1666
1667impl<'a> Build<'a> for PairWiseStart {
1668	fn build(_: &Parser<'a>, c: Cursor) -> Self {
1669		Self(c)
1670	}
1671}
1672
1673/// Represents a token with either [Kind::RightCurly], [Kind::RightParen] or [Kind::RightSquare]. Use
1674/// [T![PairWiseEnd]][crate::T] to refer to this.
1675#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1676#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
1677pub struct PairWiseEnd(Cursor);
1678cursor_wrapped!(PairWiseEnd);
1679
1680impl PairWiseEnd {
1681	pub fn kind(&self) -> Kind {
1682		self.0.token().kind()
1683	}
1684
1685	pub fn start(&self) -> Kind {
1686		match self.kind() {
1687			Kind::RightCurly => Kind::LeftCurly,
1688			Kind::RightParen => Kind::LeftParen,
1689			Kind::RightSquare => Kind::LeftSquare,
1690			k => k,
1691		}
1692	}
1693}
1694
1695impl<'a> Peek<'a> for PairWiseEnd {
1696	const PEEK_KINDSET: KindSet = KindSet::new(&[Kind::RightCurly, Kind::RightSquare, Kind::RightParen]);
1697}
1698
1699impl<'a> Build<'a> for PairWiseEnd {
1700	fn build(_: &Parser<'a>, c: Cursor) -> Self {
1701		Self(c)
1702	}
1703}
1704
1705/// The [T!][crate::T] macro expands to the name of a type representing the Token of the same name. These can be used in struct
1706/// fields to type child nodes.
1707#[macro_export]
1708macro_rules! T {
1709	[:] => { $crate::token_macros::Colon };
1710	[;] => { $crate::token_macros::Semicolon };
1711	[,] => { $crate::token_macros::Comma };
1712	['{'] => { $crate::token_macros::LeftCurly };
1713	['}'] => { $crate::token_macros::RightCurly };
1714	['['] => { $crate::token_macros::LeftSquare };
1715	[']'] => { $crate::token_macros::RightSquare };
1716	['('] => { $crate::token_macros::LeftParen };
1717	[')'] => { $crate::token_macros::RightParen };
1718	[' '] => { $crate::token_macros::Whitespace };
1719
1720	[&] => { $crate::token_macros::delim::And };
1721	[@] => { $crate::token_macros::delim::At };
1722	[^] => { $crate::token_macros::delim::Caret };
1723	[-] => { $crate::token_macros::delim::Dash };
1724	[$] => { $crate::token_macros::delim::Dollar };
1725	[.] => { $crate::token_macros::delim::Dot };
1726	[=] => { $crate::token_macros::delim::Eq };
1727	[>] => { $crate::token_macros::delim::Gt };
1728	[#] => { $crate::token_macros::delim::Hash };
1729	[<] => { $crate::token_macros::delim::Lt };
1730	[!] => { $crate::token_macros::delim::Bang };
1731	[|] => { $crate::token_macros::delim::Or };
1732	[%] => { $crate::token_macros::delim::Percent };
1733	[+] => { $crate::token_macros::delim::Plus };
1734	[?] => { $crate::token_macros::delim::Question };
1735	[/] => { $crate::token_macros::delim::Slash };
1736	[*] => { $crate::token_macros::delim::Star };
1737	[~] => { $crate::token_macros::delim::Tilde };
1738	[_] => { $crate::token_macros::delim::Underscore };
1739	['`'] => { $crate::token_macros::delim::Backtick };
1740
1741	[>=] => { $crate::token_macros::double::GreaterThanEqual };
1742	[<=] => { $crate::token_macros::double::LessThanEqual };
1743	[*|] => { $crate::token_macros::double::StarPipe };
1744	[::] => { $crate::token_macros::double::ColonColon };
1745	[||] => { $crate::token_macros::double::PipePipe };
1746	[==] => { $crate::token_macros::double::EqualEqual };
1747	[~=] => { $crate::token_macros::double::TildeEqual };
1748	[|=] => { $crate::token_macros::double::PipeEqual };
1749	[^=] => { $crate::token_macros::double::CaretEqual };
1750	["$="] => { $crate::token_macros::double::DollarEqual };
1751	[*=] => { $crate::token_macros::double::StarEqual };
1752
1753	[Dimension::$ident: ident] => { $crate::token_macros::dimension::$ident };
1754	[Dimension::%] => { $crate::token_macros::dimension::Percent };
1755	[DimensionIdent] => { $crate::token_macros::DimensionIdent };
1756
1757	[!important] => { $crate::token_macros::double::BangImportant };
1758
1759	[$ident:ident] => { $crate::token_macros::$ident }
1760}
1761
1762#[cfg(test)]
1763mod tests {
1764	use crate::{Cursor, DimensionUnit, Parser};
1765	use bumpalo::Bump;
1766
1767	#[test]
1768	fn test_custom_dimension() {
1769		custom_dimension!(Px, "px");
1770		let allocator = Bump::new();
1771		let mut p = Parser::new(&allocator, "1px");
1772		let result = p.parse_entirely::<Px>();
1773		assert!(matches!(result.output, Some(Px(_))));
1774		let c: Cursor = result.output.unwrap().into();
1775		assert!(c.token().value() == 1.0);
1776		assert!(c.token().dimension_unit() == DimensionUnit::Px);
1777		let mut p = Parser::new(&allocator, "1rem");
1778		let result = p.parse_entirely::<Px>();
1779		assert!(result.output.is_none());
1780	}
1781}