Skip to main content

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