time_macros/
to_tokens.rs

1use std::num::NonZero;
2
3use proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
4
5/// Turn a type into a [`TokenStream`].
6pub(crate) trait ToTokenStream: Sized {
7    fn append_to(self, ts: &mut TokenStream);
8    fn into_token_stream(self) -> TokenStream {
9        let mut ts = TokenStream::new();
10        self.append_to(&mut ts);
11        ts
12    }
13}
14
15pub(crate) trait ToTokenTree: Sized {
16    fn into_token_tree(self) -> TokenTree;
17}
18
19impl<T: ToTokenTree> ToTokenStream for T {
20    fn append_to(self, ts: &mut TokenStream) {
21        ts.extend([self.into_token_tree()])
22    }
23}
24
25impl ToTokenTree for bool {
26    fn into_token_tree(self) -> TokenTree {
27        let lit = if self { "true" } else { "false" };
28        TokenTree::Ident(Ident::new(lit, Span::mixed_site()))
29    }
30}
31
32impl ToTokenStream for TokenStream {
33    fn append_to(self, ts: &mut TokenStream) {
34        ts.extend(self)
35    }
36}
37
38impl ToTokenTree for TokenTree {
39    fn into_token_tree(self) -> TokenTree {
40        self
41    }
42}
43
44impl ToTokenTree for &str {
45    fn into_token_tree(self) -> TokenTree {
46        TokenTree::Literal(Literal::string(self))
47    }
48}
49
50impl ToTokenTree for NonZero<u16> {
51    fn into_token_tree(self) -> TokenTree {
52        quote_group! {{
53            unsafe { ::core::num::NonZero::<u16>::new_unchecked(#(self.get())) }
54        }}
55    }
56}
57
58macro_rules! impl_for_tree_types {
59    ($($type:ty)*) => {$(
60        impl ToTokenTree for $type {
61            fn into_token_tree(self) -> TokenTree {
62                TokenTree::from(self)
63            }
64        }
65    )*};
66}
67impl_for_tree_types![Ident Literal Group Punct];
68
69macro_rules! impl_for_int {
70    ($($type:ty => $method:ident)*) => {$(
71        impl ToTokenTree for $type {
72            fn into_token_tree(self) -> TokenTree {
73                TokenTree::from(Literal::$method(self))
74            }
75        }
76    )*};
77}
78impl_for_int! {
79    i8 => i8_unsuffixed
80    u8 => u8_unsuffixed
81    u16 => u16_unsuffixed
82    i32 => i32_unsuffixed
83    u32 => u32_unsuffixed
84}