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        {
    use proc_macro::*;
    TokenTree::Group(Group::new(Delimiter::Brace,
            {
                use proc_macro::*;
                let mut ts = TokenStream::new();
                let ts_mut = &mut ts;
                ts_mut.extend([TokenTree::from(Ident::new(&"unsafe",
                                    Span::mixed_site()))]);
                ts_mut.extend([TokenTree::Group(Group::new(Delimiter::Brace,
                                    {
                                        use proc_macro::*;
                                        let mut ts = TokenStream::new();
                                        let ts_mut = &mut ts;
                                        ts_mut.extend([TokenTree::from(Punct::new(':',
                                                            Spacing::Joint)),
                                                    TokenTree::from(Punct::new(':', Spacing::Alone))]);
                                        ;
                                        ts_mut.extend([TokenTree::from(Ident::new(&"core",
                                                            Span::mixed_site()))]);
                                        ts_mut.extend([TokenTree::from(Punct::new(':',
                                                            Spacing::Joint)),
                                                    TokenTree::from(Punct::new(':', Spacing::Alone))]);
                                        ;
                                        ts_mut.extend([TokenTree::from(Ident::new(&"num",
                                                            Span::mixed_site()))]);
                                        ts_mut.extend([TokenTree::from(Punct::new(':',
                                                            Spacing::Joint)),
                                                    TokenTree::from(Punct::new(':', Spacing::Alone))]);
                                        ;
                                        ts_mut.extend([TokenTree::from(Ident::new(&"NonZero",
                                                            Span::mixed_site()))]);
                                        ts_mut.extend([TokenTree::from(Punct::new(':',
                                                            Spacing::Joint)),
                                                    TokenTree::from(Punct::new(':', Spacing::Alone))]);
                                        ;
                                        ts_mut.extend([TokenTree::from(Punct::new('<',
                                                            Spacing::Alone))]);
                                        ;
                                        ts_mut.extend([TokenTree::from(Ident::new(&"u16",
                                                            Span::mixed_site()))]);
                                        ts_mut.extend([TokenTree::from(Punct::new('>',
                                                            Spacing::Alone))]);
                                        ;
                                        ts_mut.extend([TokenTree::from(Punct::new(':',
                                                            Spacing::Joint)),
                                                    TokenTree::from(Punct::new(':', Spacing::Alone))]);
                                        ;
                                        ts_mut.extend([TokenTree::from(Ident::new(&"new_unchecked",
                                                            Span::mixed_site()))]);
                                        ts_mut.extend([TokenTree::Group(Group::new(Delimiter::Parenthesis,
                                                            {
                                                                use proc_macro::*;
                                                                let mut ts = TokenStream::new();
                                                                let ts_mut = &mut ts;
                                                                ts_mut.extend([crate::to_tokens::ToTokenTree::into_token_tree(self.get())]);
                                                                ;
                                                                ts
                                                            }))]);
                                        ;
                                        ts
                                    }))]);
                ;
                ts
            }))
}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 ToTokenTree for Punct {
    fn into_token_tree(self) -> TokenTree { TokenTree::from(self) }
}impl_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 ToTokenTree for u32 {
    fn into_token_tree(self) -> TokenTree {
        TokenTree::from(Literal::u32_unsuffixed(self))
    }
}impl_for_int! {
79    i8 => i8_unsuffixed
80    u8 => u8_unsuffixed
81    u16 => u16_unsuffixed
82    i32 => i32_unsuffixed
83    u32 => u32_unsuffixed
84}