1use super::TokenStreamExt;
2
3use std::borrow::Cow;
4use std::iter;
5use std::rc::Rc;
6
7use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
8
9pub trait ToTokens {
13 fn to_tokens(&self, tokens: &mut TokenStream);
56
57 fn to_token_stream(&self) -> TokenStream {
62 let mut tokens = TokenStream::new();
63 self.to_tokens(&mut tokens);
64 tokens
65 }
66
67 fn into_token_stream(self) -> TokenStream
72 where
73 Self: Sized,
74 {
75 self.to_token_stream()
76 }
77}
78
79impl<'a, T: ?Sized + ToTokens> ToTokens for &'a T {
80 fn to_tokens(&self, tokens: &mut TokenStream) {
81 (**self).to_tokens(tokens);
82 }
83}
84
85impl<'a, T: ?Sized + ToTokens> ToTokens for &'a mut T {
86 fn to_tokens(&self, tokens: &mut TokenStream) {
87 (**self).to_tokens(tokens);
88 }
89}
90
91impl<'a, T: ?Sized + ToOwned + ToTokens> ToTokens for Cow<'a, T> {
92 fn to_tokens(&self, tokens: &mut TokenStream) {
93 (**self).to_tokens(tokens);
94 }
95}
96
97impl<T: ?Sized + ToTokens> ToTokens for Box<T> {
98 fn to_tokens(&self, tokens: &mut TokenStream) {
99 (**self).to_tokens(tokens);
100 }
101}
102
103impl<T: ?Sized + ToTokens> ToTokens for Rc<T> {
104 fn to_tokens(&self, tokens: &mut TokenStream) {
105 (**self).to_tokens(tokens);
106 }
107}
108
109impl<T: ToTokens> ToTokens for Option<T> {
110 fn to_tokens(&self, tokens: &mut TokenStream) {
111 if let Some(ref t) = *self {
112 t.to_tokens(tokens);
113 }
114 }
115}
116
117impl ToTokens for str {
118 fn to_tokens(&self, tokens: &mut TokenStream) {
119 tokens.append(Literal::string(self));
120 }
121}
122
123impl ToTokens for String {
124 fn to_tokens(&self, tokens: &mut TokenStream) {
125 self.as_str().to_tokens(tokens);
126 }
127}
128
129macro_rules! primitive {
130 ($($t:ident => $name:ident)*) => ($(
131 impl ToTokens for $t {
132 fn to_tokens(&self, tokens: &mut TokenStream) {
133 tokens.append(Literal::$name(*self));
134 }
135 }
136 )*)
137}
138
139primitive! {
140 i8 => i8_suffixed
141 i16 => i16_suffixed
142 i32 => i32_suffixed
143 i64 => i64_suffixed
144 i128 => i128_suffixed
145 isize => isize_suffixed
146
147 u8 => u8_suffixed
148 u16 => u16_suffixed
149 u32 => u32_suffixed
150 u64 => u64_suffixed
151 u128 => u128_suffixed
152 usize => usize_suffixed
153
154 f32 => f32_suffixed
155 f64 => f64_suffixed
156}
157
158impl ToTokens for char {
159 fn to_tokens(&self, tokens: &mut TokenStream) {
160 tokens.append(Literal::character(*self));
161 }
162}
163
164impl ToTokens for bool {
165 fn to_tokens(&self, tokens: &mut TokenStream) {
166 let word = if *self { "true" } else { "false" };
167 tokens.append(Ident::new(word, Span::call_site()));
168 }
169}
170
171impl ToTokens for Group {
172 fn to_tokens(&self, tokens: &mut TokenStream) {
173 tokens.append(self.clone());
174 }
175}
176
177impl ToTokens for Ident {
178 fn to_tokens(&self, tokens: &mut TokenStream) {
179 tokens.append(self.clone());
180 }
181}
182
183impl ToTokens for Punct {
184 fn to_tokens(&self, tokens: &mut TokenStream) {
185 tokens.append(self.clone());
186 }
187}
188
189impl ToTokens for Literal {
190 fn to_tokens(&self, tokens: &mut TokenStream) {
191 tokens.append(self.clone());
192 }
193}
194
195impl ToTokens for TokenTree {
196 fn to_tokens(&self, dst: &mut TokenStream) {
197 dst.append(self.clone());
198 }
199}
200
201impl ToTokens for TokenStream {
202 fn to_tokens(&self, dst: &mut TokenStream) {
203 dst.extend(iter::once(self.clone()));
204 }
205
206 fn into_token_stream(self) -> TokenStream {
207 self
208 }
209}