1use super::TokenStreamExt;
2use alloc::borrow::Cow;
3use alloc::rc::Rc;
4use core::iter;
5use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
6use std::ffi::{CStr, CString};
7
8pub trait ToTokens {
10    fn to_tokens(&self, tokens: &mut TokenStream);
51
52    fn to_token_stream(&self) -> TokenStream {
57        let mut tokens = TokenStream::new();
58        self.to_tokens(&mut tokens);
59        tokens
60    }
61
62    fn into_token_stream(self) -> TokenStream
67    where
68        Self: Sized,
69    {
70        self.to_token_stream()
71    }
72}
73
74impl<T: ?Sized + ToTokens> ToTokens for &T {
75    fn to_tokens(&self, tokens: &mut TokenStream) {
76        (**self).to_tokens(tokens);
77    }
78}
79
80impl<T: ?Sized + ToTokens> ToTokens for &mut T {
81    fn to_tokens(&self, tokens: &mut TokenStream) {
82        (**self).to_tokens(tokens);
83    }
84}
85
86impl<'a, T: ?Sized + ToOwned + ToTokens> ToTokens for Cow<'a, T> {
87    fn to_tokens(&self, tokens: &mut TokenStream) {
88        (**self).to_tokens(tokens);
89    }
90}
91
92impl<T: ?Sized + ToTokens> ToTokens for Box<T> {
93    fn to_tokens(&self, tokens: &mut TokenStream) {
94        (**self).to_tokens(tokens);
95    }
96}
97
98impl<T: ?Sized + ToTokens> ToTokens for Rc<T> {
99    fn to_tokens(&self, tokens: &mut TokenStream) {
100        (**self).to_tokens(tokens);
101    }
102}
103
104impl<T: ToTokens> ToTokens for Option<T> {
105    fn to_tokens(&self, tokens: &mut TokenStream) {
106        if let Some(t) = self {
107            t.to_tokens(tokens);
108        }
109    }
110}
111
112impl ToTokens for str {
113    fn to_tokens(&self, tokens: &mut TokenStream) {
114        tokens.append(Literal::string(self));
115    }
116}
117
118impl ToTokens for String {
119    fn to_tokens(&self, tokens: &mut TokenStream) {
120        self.as_str().to_tokens(tokens);
121    }
122}
123
124impl ToTokens for i8 {
125    fn to_tokens(&self, tokens: &mut TokenStream) {
126        tokens.append(Literal::i8_suffixed(*self));
127    }
128}
129
130impl ToTokens for i16 {
131    fn to_tokens(&self, tokens: &mut TokenStream) {
132        tokens.append(Literal::i16_suffixed(*self));
133    }
134}
135
136impl ToTokens for i32 {
137    fn to_tokens(&self, tokens: &mut TokenStream) {
138        tokens.append(Literal::i32_suffixed(*self));
139    }
140}
141
142impl ToTokens for i64 {
143    fn to_tokens(&self, tokens: &mut TokenStream) {
144        tokens.append(Literal::i64_suffixed(*self));
145    }
146}
147
148impl ToTokens for i128 {
149    fn to_tokens(&self, tokens: &mut TokenStream) {
150        tokens.append(Literal::i128_suffixed(*self));
151    }
152}
153
154impl ToTokens for isize {
155    fn to_tokens(&self, tokens: &mut TokenStream) {
156        tokens.append(Literal::isize_suffixed(*self));
157    }
158}
159
160impl ToTokens for u8 {
161    fn to_tokens(&self, tokens: &mut TokenStream) {
162        tokens.append(Literal::u8_suffixed(*self));
163    }
164}
165
166impl ToTokens for u16 {
167    fn to_tokens(&self, tokens: &mut TokenStream) {
168        tokens.append(Literal::u16_suffixed(*self));
169    }
170}
171
172impl ToTokens for u32 {
173    fn to_tokens(&self, tokens: &mut TokenStream) {
174        tokens.append(Literal::u32_suffixed(*self));
175    }
176}
177
178impl ToTokens for u64 {
179    fn to_tokens(&self, tokens: &mut TokenStream) {
180        tokens.append(Literal::u64_suffixed(*self));
181    }
182}
183
184impl ToTokens for u128 {
185    fn to_tokens(&self, tokens: &mut TokenStream) {
186        tokens.append(Literal::u128_suffixed(*self));
187    }
188}
189
190impl ToTokens for usize {
191    fn to_tokens(&self, tokens: &mut TokenStream) {
192        tokens.append(Literal::usize_suffixed(*self));
193    }
194}
195
196impl ToTokens for f32 {
197    fn to_tokens(&self, tokens: &mut TokenStream) {
198        tokens.append(Literal::f32_suffixed(*self));
199    }
200}
201
202impl ToTokens for f64 {
203    fn to_tokens(&self, tokens: &mut TokenStream) {
204        tokens.append(Literal::f64_suffixed(*self));
205    }
206}
207
208impl ToTokens for char {
209    fn to_tokens(&self, tokens: &mut TokenStream) {
210        tokens.append(Literal::character(*self));
211    }
212}
213
214impl ToTokens for bool {
215    fn to_tokens(&self, tokens: &mut TokenStream) {
216        let word = if *self { "true" } else { "false" };
217        tokens.append(Ident::new(word, Span::call_site()));
218    }
219}
220
221impl ToTokens for CStr {
222    fn to_tokens(&self, tokens: &mut TokenStream) {
223        tokens.append(Literal::c_string(self));
224    }
225}
226
227impl ToTokens for CString {
228    fn to_tokens(&self, tokens: &mut TokenStream) {
229        tokens.append(Literal::c_string(self));
230    }
231}
232
233impl ToTokens for Group {
234    fn to_tokens(&self, tokens: &mut TokenStream) {
235        tokens.append(self.clone());
236    }
237}
238
239impl ToTokens for Ident {
240    fn to_tokens(&self, tokens: &mut TokenStream) {
241        tokens.append(self.clone());
242    }
243}
244
245impl ToTokens for Punct {
246    fn to_tokens(&self, tokens: &mut TokenStream) {
247        tokens.append(self.clone());
248    }
249}
250
251impl ToTokens for Literal {
252    fn to_tokens(&self, tokens: &mut TokenStream) {
253        tokens.append(self.clone());
254    }
255}
256
257impl ToTokens for TokenTree {
258    fn to_tokens(&self, tokens: &mut TokenStream) {
259        tokens.append(self.clone());
260    }
261}
262
263impl ToTokens for TokenStream {
264    fn to_tokens(&self, tokens: &mut TokenStream) {
265        tokens.extend(iter::once(self.clone()));
266    }
267
268    fn into_token_stream(self) -> TokenStream {
269        self
270    }
271}