1use std::num::NonZero;
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 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}