1use crate::{IntoTokens, Parse, ProcMacro, ToTokenStream, ToTokens};
2use std::fmt::Display;
3
4#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub enum TokenTreeKind {
8 Group,
10
11 Ident,
13
14 Punct,
16
17 Literal,
19}
20
21pub trait TokenTree:
28 ProcMacro<TokenTree = Self>
29 + Display
30 + From<Self::Group>
31 + From<Self::Ident>
32 + From<Self::Punct>
33 + From<Self::Literal>
34{
35 fn span(&self) -> Self::Span;
37
38 fn set_span(&mut self, span: Self::Span);
40}
41
42pub trait TokenTreeExt:
47 crate::ProcMacroExt<TokenTreeExt = Self>
48 + TokenTree
49 + Parse<Self>
50 + IntoTokens<Self>
51 + ToTokens<Self>
52 + ToTokenStream<Self::TokenStreamExt>
53{
54 fn kind(&self) -> TokenTreeKind;
56
57 #[inline]
59 fn is_group(&self) -> bool {
60 self.kind() == TokenTreeKind::Group
61 }
62
63 fn group(&self) -> Option<&Self::Group>;
65
66 fn group_mut(&mut self) -> Option<&mut Self::Group>;
68
69 fn into_group(self) -> Option<Self::Group>;
71
72 #[inline]
74 fn is_ident(&self) -> bool {
75 self.kind() == TokenTreeKind::Ident
76 }
77
78 fn ident(&self) -> Option<&Self::Ident>;
80
81 fn ident_mut(&mut self) -> Option<&mut Self::Ident>;
83
84 fn into_ident(self) -> Option<Self::Ident>;
86
87 #[inline]
89 fn is_punct(&self) -> bool {
90 self.kind() == TokenTreeKind::Punct
91 }
92
93 fn punct(&self) -> Option<&Self::Punct>;
95
96 fn punct_mut(&mut self) -> Option<&mut Self::Punct>;
98
99 fn into_punct(self) -> Option<Self::Punct>;
101
102 #[inline]
104 fn is_literal(&self) -> bool {
105 self.kind() == TokenTreeKind::Literal
106 }
107
108 fn literal(&self) -> Option<&Self::Literal>;
110
111 fn literal_mut(&mut self) -> Option<&mut Self::Literal>;
113
114 fn into_literal(self) -> Option<Self::Literal>;
116
117 #[inline]
120 fn flatten_group(&mut self) {
121 if let Some(group) = self.group() {
122 if let Some(tt) = group.flatten() {
123 *self = tt;
124 }
125 }
126 }
127}
128
129pub trait Group: ProcMacro<Group = Self> + Display {
136 fn new(delimiter: Self::Delimiter, stream: Self::TokenStream) -> Self;
138
139 fn delimiter(&self) -> Self::Delimiter;
141
142 fn stream(&self) -> Self::TokenStream;
144
145 fn span(&self) -> Self::Span;
147
148 fn span_open(&self) -> Self::Span;
150
151 fn span_close(&self) -> Self::Span;
153
154 fn set_span(&mut self, span: Self::Span);
156}
157
158pub trait GroupExt:
163 crate::ProcMacroExt<GroupExt = Self>
164 + Group
165 + Parse<Self::TokenTree>
166 + IntoTokens<Self::TokenTree>
167 + ToTokens<Self::TokenTree>
168 + ToTokenStream<Self::TokenStream>
169{
170 fn with_span(delimiter: Self::Delimiter, stream: Self::TokenStream, span: Self::Span) -> Self {
172 let mut group = Self::new(delimiter, stream);
173 group.set_span(span);
174 group
175 }
176
177 #[inline]
179 fn delimiter_kind(&self) -> DelimiterKind {
180 self.delimiter().into()
181 }
182
183 fn stream_buffer(&self) -> crate::TokenBuffer<Self::TokenTree>;
185
186 #[inline]
190 fn flatten(&self) -> Option<Self::TokenTree> {
191 if self.delimiter().is_none() {
192 let mut stream = self.stream().into_iter();
193 if let Some(tt) = stream.next() {
194 if stream.next().is_none() {
195 if let Some(group) = tt.group() {
196 if let Some(tt) = group.flatten() {
197 return Some(tt);
198 }
199 }
200 return Some(tt);
201 }
202 }
203 }
204 None
205 }
206}
207
208#[derive(Clone, Copy, Debug, PartialEq, Eq)]
211pub enum DelimiterKind {
212 Parenthesis,
214
215 Brace,
217
218 Bracket,
220
221 None,
223}
224
225#[allow(non_upper_case_globals)]
232pub trait Delimiter: ProcMacro<Delimiter = Self> + Copy + Eq {
233 const Parenthesis: Self;
235
236 const Brace: Self;
238
239 const Bracket: Self;
241
242 const None: Self;
244}
245
246pub trait DelimiterExt:
251 crate::ProcMacroExt<DelimiterExt = Self>
252 + Delimiter
253 + From<DelimiterKind>
254 + Into<DelimiterKind>
255 + PartialEq<DelimiterKind>
256{
257 #[inline]
259 fn kind(&self) -> DelimiterKind {
260 (*self).into()
261 }
262
263 #[inline]
265 fn is_parenthesis(&self) -> bool {
266 *self == Self::Parenthesis
267 }
268
269 #[inline]
271 fn is_brace(&self) -> bool {
272 *self == Self::Brace
273 }
274
275 #[inline]
277 fn is_bracket(&self) -> bool {
278 *self == Self::Bracket
279 }
280
281 #[inline]
283 fn is_none(&self) -> bool {
284 *self == Self::None
285 }
286}
287
288pub trait Ident: ProcMacro<Ident = Self> + Display {
295 fn new(string: &str, span: Self::Span) -> Self;
297
298 fn new_raw(string: &str, span: Self::Span) -> Self;
300
301 fn span(&self) -> Self::Span;
303
304 fn set_span(&mut self, span: Self::Span);
306}
307
308pub trait IdentExt:
313 crate::ProcMacroExt<IdentExt = Self>
314 + Ident
315 + Parse<Self::TokenTree>
316 + IntoTokens<Self::TokenTree>
317 + ToTokens<Self::TokenTree>
318 + ToTokenStream<Self::TokenStream>
319{
320}
321
322pub trait Punct: ProcMacro<Punct = Self> + Display {
329 fn new(ch: char, spacing: Self::Spacing) -> Self;
331
332 fn as_char(&self) -> char;
334
335 fn spacing(&self) -> Self::Spacing;
337
338 fn span(&self) -> Self::Span;
340
341 fn set_span(&mut self, span: Self::Span);
343}
344
345pub trait PunctExt:
350 crate::ProcMacroExt<PunctExt = Self>
351 + Punct
352 + Parse<Self::TokenTree>
353 + IntoTokens<Self::TokenTree>
354 + ToTokens<Self::TokenTree>
355 + ToTokenStream<Self::TokenStream>
356{
357 #[inline]
359 fn with_span(ch: char, spacing: Self::Spacing, span: Self::Span) -> Self {
360 let mut punct = Self::Punct::new(ch, spacing);
361 punct.set_span(span);
362 punct
363 }
364
365 #[inline]
367 fn set_spacing(&mut self, spacing: Self::Spacing) {
368 *self = Self::with_span(self.as_char(), spacing, self.span());
369 }
370}
371
372#[allow(non_upper_case_globals)]
379pub trait Spacing: ProcMacro<Spacing = Self> + Copy + Eq {
380 const Joint: Self;
382
383 const Alone: Self;
385}
386
387pub trait SpacingExt: crate::ProcMacroExt<SpacingExt = Self> + Spacing {
392 #[inline]
394 fn is_joint(&self) -> bool {
395 *self == Self::Joint
396 }
397
398 #[inline]
400 fn is_alone(&self) -> bool {
401 *self == Self::Alone
402 }
403}
404
405macro_rules! impl_token_tree {
406 ($($pm:ident: $feature:literal),*) => { $(
407 #[cfg(feature = $feature)]
408 impl TokenTree for $pm::TokenTree {
409 #[inline]
410 fn span(&self) -> Self::Span {
411 self.span()
412 }
413
414 #[inline]
415 fn set_span(&mut self, span: Self::Span) {
416 self.set_span(span);
417 }
418 }
419
420 #[cfg(feature = $feature)]
421 impl TokenTreeExt for $pm::TokenTree {
422 #[inline]
423 fn kind(&self) -> TokenTreeKind {
424 match self {
425 Self::Group(_) => TokenTreeKind::Group,
426 Self::Ident(_) => TokenTreeKind::Ident,
427 Self::Punct(_) => TokenTreeKind::Punct,
428 Self::Literal(_) => TokenTreeKind::Literal,
429 }
430 }
431
432 #[inline]
433 fn group(&self) -> Option<&<Self as ProcMacro>::Group> {
434 if let Self::Group(group) = self {
435 Some(group)
436 } else {
437 None
438 }
439 }
440
441 #[inline]
442 fn group_mut(&mut self) -> Option<&mut <Self as ProcMacro>::Group> {
443 if let Self::Group(group) = self {
444 Some(group)
445 } else {
446 None
447 }
448 }
449
450 #[inline]
451 fn into_group(self) -> Option<<Self as ProcMacro>::Group> {
452 if let Self::Group(group) = self {
453 Some(group)
454 } else {
455 None
456 }
457 }
458
459 #[inline]
460 fn ident(&self) -> Option<&<Self as ProcMacro>::Ident> {
461 if let Self::Ident(ident) = self {
462 Some(ident)
463 } else {
464 None
465 }
466 }
467
468 #[inline]
469 fn ident_mut(&mut self) -> Option<&mut <Self as ProcMacro>::Ident> {
470 if let Self::Ident(ident) = self {
471 Some(ident)
472 } else {
473 None
474 }
475 }
476
477 #[inline]
478 fn into_ident(self) -> Option<<Self as ProcMacro>::Ident> {
479 if let Self::Ident(ident) = self {
480 Some(ident)
481 } else {
482 None
483 }
484 }
485
486 #[inline]
487 fn punct(&self) -> Option<&<Self as ProcMacro>::Punct> {
488 if let Self::Punct(punct) = self {
489 Some(punct)
490 } else {
491 None
492 }
493 }
494
495 #[inline]
496 fn punct_mut(&mut self) -> Option<&mut <Self as ProcMacro>::Punct> {
497 if let Self::Punct(punct) = self {
498 Some(punct)
499 } else {
500 None
501 }
502 }
503
504 #[inline]
505 fn into_punct(self) -> Option<<Self as ProcMacro>::Punct> {
506 if let Self::Punct(punct) = self {
507 Some(punct)
508 } else {
509 None
510 }
511 }
512
513 #[inline]
514 fn literal(&self) -> Option<&<Self as ProcMacro>::Literal> {
515 if let Self::Literal(literal) = self {
516 Some(literal)
517 } else {
518 None
519 }
520 }
521
522 #[inline]
523 fn literal_mut(&mut self) -> Option<&mut <Self as ProcMacro>::Literal> {
524 if let Self::Literal(literal) = self {
525 Some(literal)
526 } else {
527 None
528 }
529 }
530
531 #[inline]
532 fn into_literal(self) -> Option<<Self as ProcMacro>::Literal> {
533 if let Self::Literal(literal) = self {
534 Some(literal)
535 } else {
536 None
537 }
538 }
539 }
540
541 #[cfg(feature = $feature)]
542 impl crate::Parse<$pm::TokenTree> for $pm::TokenTree {
543 #[inline]
544 fn parse(buf: &mut &crate::TokenBuf<$pm::TokenTree>) -> Result<Self, crate::Error<$pm::Span>> {
545 if let Some(tt) = buf.first() {
546 let result = tt.clone();
547 *buf = &buf[1..];
548 Ok(result)
549 } else {
550 Err(crate::Error::new("unexpected end of input"))
551 }
552 }
553 }
554
555 #[cfg(all(feature = $feature))]
556 impl crate::IntoTokens<$pm::TokenTree> for $pm::TokenTree {
557 #[inline]
558 fn into_tokens(mut self) -> impl Iterator<Item = $pm::TokenTree> {
559 self.flatten_group();
560 std::iter::once(self)
561 }
562 }
563
564 #[cfg(feature = $feature)]
565 impl crate::ToTokenStream<$pm::TokenStream> for $pm::TokenTree {
566 #[inline]
567 fn extend_token_stream(&self, token_stream: &mut $pm::TokenStream) {
568 token_stream.extend(self.clone().into_tokens())
569 }
570 }
571
572 #[cfg(feature = $feature)]
573 impl Group for $pm::Group {
574 #[inline]
575 fn new(delimiter: Self::Delimiter, stream: Self::TokenStream) -> Self {
576 Self::new(delimiter, stream)
577 }
578
579 #[inline]
580 fn delimiter(&self) -> Self::Delimiter {
581 self.delimiter()
582 }
583
584 #[inline]
585 fn stream(&self) -> Self::TokenStream {
586 self.stream()
587 }
588
589 #[inline]
590 fn span(&self) -> Self::Span {
591 self.span()
592 }
593
594 #[inline]
595 fn span_open(&self) -> Self::Span {
596 self.span_open()
597 }
598
599 #[inline]
600 fn span_close(&self) -> Self::Span {
601 self.span_close()
602 }
603
604 #[inline]
605 fn set_span(&mut self, span: Self::Span) {
606 self.set_span(span)
607 }
608 }
609
610 #[cfg(feature = $feature)]
611 impl GroupExt for $pm::Group {
612 #[inline]
613 fn stream_buffer(&self) -> crate::TokenBuffer<$pm::TokenTree> {
614 crate::TokenBuffer::from(self.stream())
615 }
616 }
617
618 #[cfg(feature = $feature)]
619 impl crate::Parse<$pm::TokenTree> for $pm::Group {
620 #[inline]
621 fn parse(buf: &mut &crate::TokenBuf<$pm::TokenTree>) -> Result<Self, crate::Error<$pm::Span>> {
622 buf.parse_prefix(|token| {
623 if let $pm::TokenTree::Group(t) = token {
624 crate::Match::Complete(t.clone())
625 } else {
626 crate::Match::NoMatch
627 }
628 }).map_err(|mut e|{ e.set_message("expected group"); e })
629 }
630 }
631
632 #[cfg(all(feature = $feature))]
633 impl crate::IntoTokens<$pm::TokenTree> for $pm::Group {
634 #[inline]
635 fn into_tokens(self) -> impl Iterator<Item = $pm::TokenTree> {
636 std::iter::once($pm::TokenTree::Group(self))
637 }
638 }
639
640 #[cfg(feature = $feature)]
641 impl crate::ToTokenStream<$pm::TokenStream> for $pm::Group {
642 #[inline]
643 fn extend_token_stream(&self, token_stream: &mut $pm::TokenStream) {
644 token_stream.extend([$pm::TokenTree::from(self.clone())])
645 }
646 }
647
648 #[cfg(feature = $feature)]
649 impl From<$pm::Delimiter> for DelimiterKind {
650 #[inline]
651 fn from(value: $pm::Delimiter) -> Self {
652 match value {
653 $pm::Delimiter::Parenthesis => Self::Parenthesis,
654 $pm::Delimiter::Brace => Self::Brace,
655 $pm::Delimiter::Bracket => Self::Bracket,
656 $pm::Delimiter::None => Self::None,
657 }
658 }
659 }
660
661 #[cfg(feature = $feature)]
662 impl From<DelimiterKind> for $pm::Delimiter {
663 #[inline]
664 fn from(value: DelimiterKind) -> Self {
665 match value {
666 DelimiterKind::Parenthesis => Self::Parenthesis,
667 DelimiterKind::Brace => Self::Brace,
668 DelimiterKind::Bracket => Self::Bracket,
669 DelimiterKind::None => Self::None,
670 }
671 }
672 }
673
674 #[cfg(feature = $feature)]
675 impl PartialEq<$pm::Delimiter> for DelimiterKind {
676 #[inline]
677 fn eq(&self, rhs: &$pm::Delimiter) -> bool {
678 *self == rhs.kind()
679 }
680 }
681
682 #[cfg(feature = $feature)]
683 impl PartialEq<DelimiterKind> for $pm::Delimiter {
684 #[inline]
685 fn eq(&self, rhs: &DelimiterKind) -> bool {
686 self.kind() == *rhs
687 }
688 }
689
690 #[cfg(feature = $feature)]
691 #[allow(non_upper_case_globals)]
692 impl Delimiter for $pm::Delimiter {
693 const Parenthesis: Self = Self::Parenthesis;
694 const Brace: Self = Self::Brace;
695 const Bracket: Self = Self::Bracket;
696 const None: Self = Self::None;
697 }
698
699 #[cfg(feature = $feature)]
700 impl DelimiterExt for $pm::Delimiter {}
701
702 #[cfg(feature = $feature)]
703 impl Ident for $pm::Ident {
704 #[inline]
705 fn new(string: &str, span: Self::Span) -> Self {
706 Self::new(string, span)
707 }
708
709 #[inline]
710 fn new_raw(string: &str, span: Self::Span) -> Self {
711 Self::new_raw(string, span)
712 }
713
714 #[inline]
715 fn span(&self) -> Self::Span {
716 self.span()
717 }
718
719 #[inline]
720 fn set_span(&mut self, span: Self::Span) {
721 self.set_span(span)
722 }
723 }
724
725 #[cfg(feature = $feature)]
726 impl IdentExt for $pm::Ident {}
727
728 #[cfg(feature = $feature)]
729 impl crate::Parse<$pm::TokenTree> for $pm::Ident {
730 #[inline]
731 fn parse(buf: &mut &crate::TokenBuf<$pm::TokenTree>) -> Result<Self, crate::Error<$pm::Span>> {
732 buf.parse_prefix(|token| {
733 if let $pm::TokenTree::Ident(t) = token {
734 crate::Match::Complete(t.clone())
735 } else {
736 crate::Match::NoMatch
737 }
738 }).map_err(|mut e|{ e.set_message("expected ident"); e })
739 }
740 }
741
742 #[cfg(all(feature = $feature))]
743 impl crate::IntoTokens<$pm::TokenTree> for $pm::Ident {
744 #[inline]
745 fn into_tokens(self) -> impl Iterator<Item = $pm::TokenTree> {
746 std::iter::once($pm::TokenTree::Ident(self))
747 }
748 }
749
750 #[cfg(feature = $feature)]
751 impl crate::ToTokenStream<$pm::TokenStream> for $pm::Ident {
752 #[inline]
753 fn extend_token_stream(&self, token_stream: &mut $pm::TokenStream) {
754 token_stream.extend([$pm::TokenTree::from(self.clone())])
755 }
756 }
757
758 #[cfg(feature = $feature)]
759 impl Punct for $pm::Punct {
760 #[inline]
761 fn new(ch: char, spacing: Self::Spacing) -> Self {
762 Self::new(ch, spacing)
763 }
764
765 #[inline]
766 fn as_char(&self) -> char {
767 self.as_char()
768 }
769
770 #[inline]
771 fn spacing(&self) -> Self::Spacing {
772 self.spacing()
773 }
774
775 #[inline]
776 fn span(&self) -> Self::Span {
777 self.span()
778 }
779
780 #[inline]
781 fn set_span(&mut self, span: Self::Span) {
782 self.set_span(span)
783 }
784 }
785
786 #[cfg(feature = $feature)]
787 impl PunctExt for $pm::Punct {}
788
789 #[cfg(feature = $feature)]
790 impl crate::Parse<$pm::TokenTree> for $pm::Punct {
791 #[inline]
792 fn parse(buf: &mut &crate::TokenBuf<$pm::TokenTree>) -> Result<Self, crate::Error<$pm::Span>> {
793 buf.parse_prefix(|token| {
794 if let $pm::TokenTree::Punct(t) = token {
795 crate::Match::Complete(t.clone())
796 } else {
797 crate::Match::NoMatch
798 }
799 }).map_err(|mut e|{ e.set_message("expected punct"); e })
800 }
801 }
802
803 #[cfg(feature = $feature)]
804 impl crate::IntoTokens<$pm::TokenTree> for $pm::Punct {
805 #[inline]
806 fn into_tokens(self) -> impl Iterator<Item = $pm::TokenTree> {
807 std::iter::once($pm::TokenTree::Punct(self))
808 }
809 }
810
811 #[cfg(feature = $feature)]
812 impl crate::ToTokenStream<$pm::TokenStream> for $pm::Punct {
813 #[inline]
814 fn extend_token_stream(&self, token_stream: &mut $pm::TokenStream) {
815 token_stream.extend([$pm::TokenTree::from(self.clone())])
816 }
817 }
818
819 #[cfg(feature = $feature)]
820 #[allow(non_upper_case_globals)]
821 impl Spacing for $pm::Spacing {
822 const Joint: Self = Self::Joint;
823 const Alone: Self = Self::Alone;
824 }
825
826 #[cfg(feature = $feature)]
827 impl SpacingExt for $pm::Spacing {}
828 )* };
829}
830
831impl_token_tree!(proc_macro: "proc-macro", proc_macro2: "proc-macro2");