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