proclet/
token_tree.rs

1use crate::{IntoTokens, Parse, ProcMacro, ToTokenStream, ToTokens};
2use std::fmt::Display;
3
4/// The kind of a `TokenTree`. This is like the enum in `proc_macro*::TokenTree`, but
5/// without any contained data. It doesn't depend on which proc-macro crate you use.
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub enum TokenTreeKind {
8    /// `TokenTree::Group`
9    Group,
10
11    /// `TokenTree::Ident`
12    Ident,
13
14    /// `TokenTree::Punct`
15    Punct,
16
17    /// `TokenTree::Literal`
18    Literal,
19}
20
21/// `TokenTree` API trait. See [`proc_macro::TokenTree`](https://doc.rust-lang.org/stable/proc_macro/enum.TokenTree.html).
22///
23/// This trait is implemented for `TokenTree` in `proc_macro` and `proc_macro2` if the
24/// corresponding feature is enabled.
25///
26/// See also [`TokenTreeExt`].
27pub 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    /// Get the span of this `TokenTree`.
36    fn span(&self) -> Self::Span;
37
38    /// Set the span of this `TokenTree`. If the `TokenTree` is a [`Group`], this will use [`Group::set_span`].
39    fn set_span(&mut self, span: Self::Span);
40}
41
42/// Extensions for [`TokenTree`].
43///
44/// This trait is implemented for `TokenTree` in `proc_macro` and `proc_macro2` if the
45/// corresponding feature is enabled.
46pub trait TokenTreeExt:
47    crate::ProcMacroExt<TokenTreeExt = Self>
48    + TokenTree
49    + Parse<Self>
50    + IntoTokens<Self>
51    + ToTokens<Self>
52    + ToTokenStream<Self::TokenStreamExt>
53{
54    /// Get the kind of this `TokenTree`.
55    fn kind(&self) -> TokenTreeKind;
56
57    /// Check if this `TokenTree` is a `TokenTree::Group`.
58    #[inline]
59    fn is_group(&self) -> bool {
60        self.kind() == TokenTreeKind::Group
61    }
62
63    /// If this `TokenTree` is a `TokenTree::Group`, return a reference to the `Group`.
64    fn group(&self) -> Option<&Self::Group>;
65
66    /// If this `TokenTree` is a `TokenTree::Group`, return a mutable reference to the `Group`.
67    fn group_mut(&mut self) -> Option<&mut Self::Group>;
68
69    /// If this `TokenTree` is a `TokenTree::Group`, return the `Group`.
70    fn into_group(self) -> Option<Self::Group>;
71
72    /// Check if this `TokenTree` is a `TokenTree::Ident`.
73    #[inline]
74    fn is_ident(&self) -> bool {
75        self.kind() == TokenTreeKind::Ident
76    }
77
78    /// If this `TokenTree` is a `TokenTree::Ident`, return a reference to the `Ident`.
79    fn ident(&self) -> Option<&Self::Ident>;
80
81    /// If this `TokenTree` is a `TokenTree::Ident`, return a mutable reference to the `Ident`.
82    fn ident_mut(&mut self) -> Option<&mut Self::Ident>;
83
84    /// If this `TokenTree` is a `TokenTree::Ident`, return the `Ident`.
85    fn into_ident(self) -> Option<Self::Ident>;
86
87    /// Check if this `TokenTree` is a `TokenTree::Punct`.
88    #[inline]
89    fn is_punct(&self) -> bool {
90        self.kind() == TokenTreeKind::Punct
91    }
92
93    /// If this `TokenTree` is a `TokenTree::Punct`, return a reference to the `Punct`.
94    fn punct(&self) -> Option<&Self::Punct>;
95
96    /// If this `TokenTree` is a `TokenTree::Punct`, return a mutable reference to the `Punct`.
97    fn punct_mut(&mut self) -> Option<&mut Self::Punct>;
98
99    /// Check if this `TokenTree` is a `TokenTree::Punct`.
100    fn into_punct(self) -> Option<Self::Punct>;
101
102    /// Check if this `TokenTree` is a `TokenTree::Literal`.
103    #[inline]
104    fn is_literal(&self) -> bool {
105        self.kind() == TokenTreeKind::Literal
106    }
107
108    /// If this `TokenTree` is a `TokenTree::Literal`, return a reference to the `Literal`.
109    fn literal(&self) -> Option<&Self::Literal>;
110
111    /// If this `TokenTree` is a `TokenTree::Literal`, return a mutable reference to the `Literal`.
112    fn literal_mut(&mut self) -> Option<&mut Self::Literal>;
113
114    /// Check if this `TokenTree` is a `TokenTree::Literal`.
115    fn into_literal(self) -> Option<Self::Literal>;
116
117    /// If the `TokenTree` is a group with delimiter `None` containing a single item,
118    /// replace the group with that item, recursively.
119    #[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
129/// `Group` API trait. See [`proc_macro::Group`](https://doc.rust-lang.org/stable/proc_macro/struct.Group.html).
130///
131/// This trait is implemented for `Group` in `proc_macro` and `proc_macro2` if the
132/// corresponding feature is enabled.
133///
134/// See also [`GroupExt`].
135pub trait Group: ProcMacro<Group = Self> + Display {
136    /// Create a new `Group`. The span will be set to `Span::call_site()`.
137    fn new(delimiter: Self::Delimiter, stream: Self::TokenStream) -> Self;
138
139    /// Get the delimiter of this `Group`.
140    fn delimiter(&self) -> Self::Delimiter;
141
142    /// Get the punctuated `TokenStream`, not including delimiters.
143    fn stream(&self) -> Self::TokenStream;
144
145    /// Get the span of this `Group`.
146    fn span(&self) -> Self::Span;
147
148    /// Get the span of the group's opening delimiter.
149    fn span_open(&self) -> Self::Span;
150
151    /// Get the span of the group's closing delimiter.
152    fn span_close(&self) -> Self::Span;
153
154    /// Set the span of this `Group`. This does *not* set the span of the contained `TokenStream`.
155    fn set_span(&mut self, span: Self::Span);
156}
157
158/// Extensions for [`Group`].
159///
160/// This trait is implemented for `Group` in `proc_macro` and `proc_macro2` if the
161/// corresponding feature is enabled.
162pub 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    /// Create a new `Group` with a custom span.
171    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    /// Get the delimiter of this `Group` as a matchable enum.
178    #[inline]
179    fn delimiter_kind(&self) -> DelimiterKind {
180        self.delimiter().into()
181    }
182
183    /// Get the punctuated `TokenStream` as a `TokenBuffer`, not including delimiters.
184    fn stream_buffer(&self) -> crate::TokenBuffer<Self::TokenTree>;
185
186    /// If the group has delimiter `None` and contains a single item, extract that item,
187    /// and if that item is a group, flatten that too, recursively. Then return the item,
188    /// or `None` if the conditions weren't met.
189    #[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/// Delimiter. This is exactly like `proc_macro*::Delimiter`, but doesn't depend on
209/// which proc-macro crate you use.
210#[derive(Clone, Copy, Debug, PartialEq, Eq)]
211pub enum DelimiterKind {
212    /// `(` ... `)`
213    Parenthesis,
214
215    /// `{` ... `}`
216    Brace,
217
218    /// `[` ... `]`
219    Bracket,
220
221    /// No delimiter.
222    None,
223}
224
225/// `Delimiter` API trait. See [`proc_macro::Delimiter`](https://doc.rust-lang.org/stable/proc_macro/enum.Delimiter.html).
226///
227/// This trait is implemented for `Delimiter` in `proc_macro` and `proc_macro2` if the
228/// corresponding feature is enabled.
229///
230/// See also [`DelimiterExt`].
231#[allow(non_upper_case_globals)]
232pub trait Delimiter: ProcMacro<Delimiter = Self> + Copy + Eq {
233    /// `proc_macro*::Delimiter::Parenthesis` (`(` ... `)`)
234    const Parenthesis: Self;
235
236    /// `proc_macro*::Delimiter::Brace` `{` ... `}`
237    const Brace: Self;
238
239    /// `proc_macro*::Delimiter::Bracket` `[` ...  `]`
240    const Bracket: Self;
241
242    /// `proc_macro*::Delimiter::None` (No delimiter)
243    const None: Self;
244}
245
246/// Extensions for [`Delimiter`].
247///
248/// This trait is implemented for `Delimiter` in `proc_macro` and `proc_macro2` if the
249/// corresponding feature is enabled.
250pub trait DelimiterExt:
251    crate::ProcMacroExt<DelimiterExt = Self>
252    + Delimiter
253    + From<DelimiterKind>
254    + Into<DelimiterKind>
255    + PartialEq<DelimiterKind>
256{
257    /// Get the kind of this `Delimiter`.
258    #[inline]
259    fn kind(&self) -> DelimiterKind {
260        (*self).into()
261    }
262
263    /// Check if this delimiter is `Delimiter::Parenthesis`.
264    #[inline]
265    fn is_parenthesis(&self) -> bool {
266        *self == Self::Parenthesis
267    }
268
269    /// Check if this delimiter is `Delimiter::Brace`.
270    #[inline]
271    fn is_brace(&self) -> bool {
272        *self == Self::Brace
273    }
274
275    /// Check if this delimiter is `Delimiter::Bracket`.
276    #[inline]
277    fn is_bracket(&self) -> bool {
278        *self == Self::Bracket
279    }
280
281    /// Check if this delimiter is `Delimiter::None`.
282    #[inline]
283    fn is_none(&self) -> bool {
284        *self == Self::None
285    }
286}
287
288/// `Ident` API trait. See [`proc_macro::Ident`](https://doc.rust-lang.org/stable/proc_macro/struct.Ident.html).
289///
290/// This trait is implemented for `Ident` in `proc_macro` and `proc_macro2` if the
291/// corresponding feature is enabled.
292///
293/// See also [`IdentExt`].
294pub trait Ident: ProcMacro<Ident = Self> + Display {
295    /// Create a new `Ident` with the specified `span`.
296    fn new(string: &str, span: Self::Span) -> Self;
297
298    /// Create a new raw identifier with the specified `span`.
299    fn new_raw(string: &str, span: Self::Span) -> Self;
300
301    /// The span of this `Ident`.
302    fn span(&self) -> Self::Span;
303
304    /// Set the span of this `Ident`.
305    fn set_span(&mut self, span: Self::Span);
306}
307
308/// Extensions for [`Ident`].
309///
310/// This trait is implemented for `Ident` in `proc_macro` and `proc_macro2` if the
311/// corresponding feature is enabled.
312pub 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
322/// `Punct` API trait. See [`proc_macro::Punct`](https://doc.rust-lang.org/stable/proc_macro/struct.Punct.html).
323///
324/// This trait is implemented for `Punct` in `proc_macro` and `proc_macro2` if the
325/// corresponding feature is enabled.
326///
327/// See also [`PunctExt`].
328pub trait Punct: ProcMacro<Punct = Self> + Display {
329    /// Create a new `Punct`.
330    fn new(ch: char, spacing: Self::Spacing) -> Self;
331
332    /// The value of this `Punct` as a `char`
333    fn as_char(&self) -> char;
334
335    /// The `Spacing` of this `Punct`.
336    fn spacing(&self) -> Self::Spacing;
337
338    /// The span of this `Punct`.
339    fn span(&self) -> Self::Span;
340
341    /// Set the span of this `Punct`.
342    fn set_span(&mut self, span: Self::Span);
343}
344
345/// Extensions for [`Punct`].
346///
347/// This trait is implemented for `Punct` in `proc_macro` and `proc_macro2` if the
348/// corresponding feature is enabled.
349pub 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    /// Create a new `Punct` with a custom `Span`.
358    #[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    /// Set the spacing of this `Punct`.
366    #[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/// `Spacing` API trait. See [`proc_macro::Spacing`](https://doc.rust-lang.org/stable/proc_macro/enum.Spacing.html).
373///
374/// This trait is implemented for `Spacing` in `proc_macro` and `proc_macro2` if the
375/// corresponding feature is enabled.
376///
377/// See also [`SpacingExt`].
378#[allow(non_upper_case_globals)]
379pub trait Spacing: ProcMacro<Spacing = Self> + Copy + Eq {
380    /// `proc_macro*::Spacing::Joint`.
381    const Joint: Self;
382
383    /// `proc_macro*::Spacing::Alone`.
384    const Alone: Self;
385}
386
387/// Extensions for [`Spacing`].
388///
389/// This trait is implemented for `Spacing` in `proc_macro` and `proc_macro2` if the
390/// corresponding feature is enabled.
391pub trait SpacingExt: crate::ProcMacroExt<SpacingExt = Self> + Spacing {
392    /// Check if this is `Spacing::Joint`.
393    #[inline]
394    fn is_joint(&self) -> bool {
395        *self == Self::Joint
396    }
397
398    /// Check if this is `Spacing::Alone`.
399    #[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");