1use proc_macro2::{Ident, Literal, Span, TokenStream};
2use quote::{quote, TokenStreamExt};
3
4pub trait ToTokenStream {
28 fn to_toks(&self, toks: &mut TokenStream);
29
30 fn to_tok_stream(&self) -> TokenStream {
31 let mut tokens = TokenStream::new();
32 self.to_toks(&mut tokens);
33 tokens
34 }
35
36 fn to_tokens(&self, toks: &mut TokenStream) {
37 self.to_toks(toks);
38 }
39}
40
41macro_rules! primitive {
42 ($($t:ty => $name:ident)*) => {
43 $(
44 impl ToTokenStream for $t {
45 fn to_toks(&self, tokens: &mut TokenStream) {
46 tokens.append(Literal::$name(*self));
47 }
48 }
49 )*
50 };
51}
52
53primitive! {
54 i8 => i8_suffixed
55 i16 => i16_suffixed
56 i32 => i32_suffixed
57 i64 => i64_suffixed
58 i128 => i128_suffixed
59 isize => isize_suffixed
60
61 u8 => u8_suffixed
62 u16 => u16_suffixed
63 u32 => u32_suffixed
64 u64 => u64_suffixed
65 u128 => u128_suffixed
66 usize => usize_suffixed
67
68 f32 => f32_suffixed
69 f64 => f64_suffixed
70
71 char => character
72 &str => string
73}
74
75impl ToTokenStream for bool {
76 fn to_toks(&self, tokens: &mut TokenStream) {
77 tokens.append(Ident::new(&self.to_string(), Span::call_site()));
78 }
79}
80
81impl<'a, T: ?Sized + ToTokenStream> ToTokenStream for &'a T {
82 fn to_toks(&self, tokens: &mut TokenStream) {
83 (**self).to_toks(tokens);
84 }
85}
86
87impl<'a, T: ?Sized + ToTokenStream> ToTokenStream for &'a mut T {
88 fn to_toks(&self, tokens: &mut TokenStream) {
89 (**self).to_toks(tokens);
90 }
91}
92
93fn to_toks_slice<T>(sl: &[T], tokens: &mut TokenStream)
94where
95 T: ToTokenStream,
96{
97 let mut arr_toks = TokenStream::new();
98 for a in sl.iter() {
99 let a_toks = a.to_tok_stream();
100 let element = quote! { #a_toks, };
101 arr_toks.extend(element);
102 }
103 let element = quote! { [#arr_toks] };
104 tokens.extend(element);
105}
106
107impl<T> ToTokenStream for &[T]
108where
109 T: ToTokenStream,
110{
111 fn to_toks(&self, tokens: &mut TokenStream) {
112 to_toks_slice(self, tokens);
113 }
114}
115
116impl<T, const N: usize> ToTokenStream for [T; N]
117where
118 T: ToTokenStream,
119{
120 fn to_toks(&self, tokens: &mut TokenStream) {
121 to_toks_slice(self, tokens);
122 }
123}
124
125impl ToTokenStream for String {
126 fn to_toks(&self, tokens: &mut TokenStream) {
127 tokens.extend(quote! { #self });
128 }
129}
130
131impl<T> ToTokenStream for Vec<T>
132where
133 T: ToTokenStream,
134{
135 fn to_toks(&self, tokens: &mut TokenStream) {
136 let mut arr_toks = TokenStream::new();
137 for a in self {
138 let a_toks = a.to_tok_stream();
139 let element = quote! { #a_toks, };
140 arr_toks.extend(element);
141 }
142 let element = quote! { vec![#arr_toks] };
143 tokens.extend(element);
144 }
145}
146
147impl<T> ToTokenStream for Option<T>
148where
149 T: ToTokenStream,
150{
151 fn to_toks(&self, tokens: &mut TokenStream) {
152 let element;
153 match self {
154 Some(a) => {
155 let a_toks = a.to_tok_stream();
156 element = quote! {
157 Some(#a_toks)
158 };
159 }
160 None => {
161 element = quote! { None };
162 }
163 }
164 tokens.extend(element);
165 }
166}
167
168macro_rules! build_tuple_trait {
169 ($($id:ident),+;$($index:literal),+) => {
170 fn to_toks(&self, tokens: &mut TokenStream) {
171 let ($($id),+) = self;
175 $(let $id = $id.to_tok_stream();)+
176 let element = quote! { ($(#$id),+) };
177 tokens.extend(element);
178 }
179 };
180}
181
182impl<T1, T2> ToTokenStream for (T1, T2)
183where
184 T1: ToTokenStream,
185 T2: ToTokenStream,
186{
187 build_tuple_trait!(t1, t2; 0, 1);
188}
189
190impl<T1, T2, T3> ToTokenStream for (T1, T2, T3)
191where
192 T1: ToTokenStream,
193 T2: ToTokenStream,
194 T3: ToTokenStream,
195{
196 build_tuple_trait!(t1, t2, t3; 0, 1, 2);
197}
198
199impl<T1, T2, T3, T4> ToTokenStream for (T1, T2, T3, T4)
200where
201 T1: ToTokenStream,
202 T2: ToTokenStream,
203 T3: ToTokenStream,
204 T4: ToTokenStream,
205{
206 build_tuple_trait!(t1, t2, t3, t4; 0, 1, 2, 3);
207}
208
209impl<T1, T2, T3, T4, T5> ToTokenStream for (T1, T2, T3, T4, T5)
210where
211 T1: ToTokenStream,
212 T2: ToTokenStream,
213 T3: ToTokenStream,
214 T4: ToTokenStream,
215 T5: ToTokenStream,
216{
217 build_tuple_trait!(t1, t2, t3, t4, t5; 0, 1, 2, 3, 4);
218}
219
220impl<T1, T2, T3, T4, T5, T6> ToTokenStream for (T1, T2, T3, T4, T5, T6)
221where
222 T1: ToTokenStream,
223 T2: ToTokenStream,
224 T3: ToTokenStream,
225 T4: ToTokenStream,
226 T5: ToTokenStream,
227 T6: ToTokenStream,
228{
229 build_tuple_trait!(t1, t2, t3, t4, t5, t6; 0, 1, 2, 3, 4, 5);
230}
231
232impl<T1, T2, T3, T4, T5, T6, T7> ToTokenStream for (T1, T2, T3, T4, T5, T6, T7)
233where
234 T1: ToTokenStream,
235 T2: ToTokenStream,
236 T3: ToTokenStream,
237 T4: ToTokenStream,
238 T5: ToTokenStream,
239 T6: ToTokenStream,
240 T7: ToTokenStream,
241{
242 build_tuple_trait!(t1, t2, t3, t4, t5, t6, t7; 0, 1, 2, 3, 4, 5, 6);
243}
244
245impl<T1, T2, T3, T4, T5, T6, T7, T8> ToTokenStream for (T1, T2, T3, T4, T5, T6, T7, T8)
246where
247 T1: ToTokenStream,
248 T2: ToTokenStream,
249 T3: ToTokenStream,
250 T4: ToTokenStream,
251 T5: ToTokenStream,
252 T6: ToTokenStream,
253 T7: ToTokenStream,
254 T8: ToTokenStream,
255{
256 build_tuple_trait!(t1, t2, t3, t4, t5, t6, t7, t8; 0, 1, 2, 3, 4, 5, 6, 7);
257}
258
259impl<T1, T2, T3, T4, T5, T6, T7, T8, T9> ToTokenStream for (T1, T2, T3, T4, T5, T6, T7, T8, T9)
260where
261 T1: ToTokenStream,
262 T2: ToTokenStream,
263 T3: ToTokenStream,
264 T4: ToTokenStream,
265 T5: ToTokenStream,
266 T6: ToTokenStream,
267 T7: ToTokenStream,
268 T8: ToTokenStream,
269 T9: ToTokenStream,
270{
271 build_tuple_trait!(t1, t2, t3, t4, t5, t6, t7, t8, t9; 0, 1, 2, 3, 4, 5, 6, 7, 8);
272}
273
274impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ToTokenStream
275 for (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
276where
277 T1: ToTokenStream,
278 T2: ToTokenStream,
279 T3: ToTokenStream,
280 T4: ToTokenStream,
281 T5: ToTokenStream,
282 T6: ToTokenStream,
283 T7: ToTokenStream,
284 T8: ToTokenStream,
285 T9: ToTokenStream,
286 T10: ToTokenStream,
287{
288 build_tuple_trait!(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
289}
290
291impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> ToTokenStream
292 for (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)
293where
294 T1: ToTokenStream,
295 T2: ToTokenStream,
296 T3: ToTokenStream,
297 T4: ToTokenStream,
298 T5: ToTokenStream,
299 T6: ToTokenStream,
300 T7: ToTokenStream,
301 T8: ToTokenStream,
302 T9: ToTokenStream,
303 T10: ToTokenStream,
304 T11: ToTokenStream,
305{
306 build_tuple_trait!(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
307}
308
309impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> ToTokenStream
310 for (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)
311where
312 T1: ToTokenStream,
313 T2: ToTokenStream,
314 T3: ToTokenStream,
315 T4: ToTokenStream,
316 T5: ToTokenStream,
317 T6: ToTokenStream,
318 T7: ToTokenStream,
319 T8: ToTokenStream,
320 T9: ToTokenStream,
321 T10: ToTokenStream,
322 T11: ToTokenStream,
323 T12: ToTokenStream,
324{
325 build_tuple_trait!(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
326}