1use std::num::NonZeroU16;
2
3use proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
4
5pub(crate) trait ToTokenStream: Sized {
7 fn append_to(self, ts: &mut 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 append_to(self, ts: &mut TokenStream) {
16 ts.extend([self.into_token_tree()])
17 }
18}
19
20impl ToTokenTree for bool {
21 fn into_token_tree(self) -> TokenTree {
22 let lit = if self { "true" } else { "false" };
23 TokenTree::Ident(Ident::new(lit, Span::mixed_site()))
24 }
25}
26
27impl ToTokenStream for TokenStream {
28 fn append_to(self, ts: &mut TokenStream) {
29 ts.extend(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 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
53macro_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}
62impl_for_tree_types![Ident Literal Group Punct];
63
64macro_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}
73impl_for_int! {
74 i8 => i8_unsuffixed
75 u8 => u8_unsuffixed
76 u16 => u16_unsuffixed
77 i32 => i32_unsuffixed
78 u32 => u32_unsuffixed
79}