proc_macro_tool/
kind.rs

1use proc_macro::{Group, Ident, Literal, Punct, TokenTree};
2
3use crate::TokenTreeExt as _;
4
5/// Enum to [`TokenTree`] variants
6///
7/// # Examples
8/// ```no_run
9/// # extern crate proc_macro;
10/// # use proc_macro_tool::{TokenKind, TokenTreeExt as _};
11/// # use proc_macro::{Punct, TokenTree, Spacing::*};
12/// let token = TokenTree::from(Punct::new('+', Alone));
13/// assert_eq!(token.kind(), TokenKind::Punct);
14/// ```
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
16pub enum TokenKind {
17    /// [`TokenTree::Group`]
18    Group,
19    /// [`TokenTree::Ident`]
20    Ident,
21    /// [`TokenTree::Punct`]
22    Punct,
23    /// [`TokenTree::Literal`]
24    Literal,
25}
26
27impl TokenKind {
28    /// Returns `true` if the token kind is [`Group`].
29    ///
30    /// [`Group`]: TokenKind::Group
31    #[must_use]
32    pub fn is_group(&self) -> bool {
33        matches!(self, Self::Group)
34    }
35
36    /// Returns `true` if the token kind is [`Ident`].
37    ///
38    /// [`Ident`]: TokenKind::Ident
39    #[must_use]
40    pub fn is_ident(&self) -> bool {
41        matches!(self, Self::Ident)
42    }
43
44    /// Returns `true` if the token kind is [`Punct`].
45    ///
46    /// [`Punct`]: TokenKind::Punct
47    #[must_use]
48    pub fn is_punct(&self) -> bool {
49        matches!(self, Self::Punct)
50    }
51
52    /// Returns `true` if the token kind is [`Literal`].
53    ///
54    /// [`Literal`]: TokenKind::Literal
55    #[must_use]
56    pub fn is_literal(&self) -> bool {
57        matches!(self, Self::Literal)
58    }
59}
60
61impl PartialEq<TokenTree> for TokenKind {
62    fn eq(&self, other: &TokenTree) -> bool {
63        *self == other.kind()
64    }
65}
66impl PartialEq<TokenKind> for TokenTree {
67    fn eq(&self, other: &TokenKind) -> bool {
68        self.kind() == *other
69    }
70}
71
72impl From<&TokenTree> for TokenKind {
73    fn from(tt: &TokenTree) -> Self {
74        match tt {
75            TokenTree::Group(_) => Self::Group,
76            TokenTree::Ident(_) => Self::Ident,
77            TokenTree::Punct(_) => Self::Punct,
78            TokenTree::Literal(_) => Self::Literal,
79        }
80    }
81}
82impl From<&mut TokenTree> for TokenKind {
83    fn from(tt: &mut TokenTree) -> Self {
84        match tt {
85            TokenTree::Group(_) => Self::Group,
86            TokenTree::Ident(_) => Self::Ident,
87            TokenTree::Punct(_) => Self::Punct,
88            TokenTree::Literal(_) => Self::Literal,
89        }
90    }
91}
92impl From<TokenTree> for TokenKind {
93    fn from(tt: TokenTree) -> Self {
94        Self::from(&tt)
95    }
96}
97macro_rules! impl_kind {
98    ($i:ident) => {
99        impl From<$i> for TokenKind {
100            fn from(_: $i) -> Self {
101                Self::$i
102            }
103        }
104        impl From<&$i> for TokenKind {
105            fn from(_: &$i) -> Self {
106                Self::$i
107            }
108        }
109        impl From<&mut $i> for TokenKind {
110            fn from(_: &mut $i) -> Self {
111                Self::$i
112            }
113        }
114    };
115}
116impl_kind!(Group);
117impl_kind!(Ident);
118impl_kind!(Punct);
119impl_kind!(Literal);