1use crate::syntax::atom::Atom::*;
2use crate::syntax::{
3 Array, Atom, Derive, Enum, EnumRepr, ExternFn, ExternType, Impl, Lifetimes, NamedType, Ptr,
4 Ref, Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var,
5};
6use proc_macro2::{Ident, Span, TokenStream};
7use quote::{quote_spanned, ToTokens};
8use syn::{token, Token};
9
10impl ToTokens for Type {
11 fn to_tokens(&self, tokens: &mut TokenStream) {
12 match self {
13 Type::Ident(ident) => {
14 if ident.rust == Char {
15 let span = ident.rust.span();
16 tokens.extend(quote_spanned!(span=> ::cxx::core::ffi::));
17 } else if ident.rust == CxxString {
18 let span = ident.rust.span();
19 tokens.extend(quote_spanned!(span=> ::cxx::));
20 } else if ident.rust == RustString {
21 let span = ident.rust.span();
22 tokens.extend(quote_spanned!(span=> ::cxx::alloc::string::));
23 }
24 ident.to_tokens(tokens);
25 }
26 Type::RustBox(ty)
27 | Type::UniquePtr(ty)
28 | Type::SharedPtr(ty)
29 | Type::WeakPtr(ty)
30 | Type::CxxVector(ty)
31 | Type::RustVec(ty) => ty.to_tokens(tokens),
32 Type::Ref(r) | Type::Str(r) => r.to_tokens(tokens),
33 Type::Ptr(p) => p.to_tokens(tokens),
34 Type::Array(a) => a.to_tokens(tokens),
35 Type::Fn(f) => f.to_tokens(tokens),
36 Type::Void(span) => tokens.extend(quote_spanned!(*span=> ())),
37 Type::SliceRef(r) => r.to_tokens(tokens),
38 }
39 }
40}
41
42impl ToTokens for Var {
43 fn to_tokens(&self, tokens: &mut TokenStream) {
44 let Var {
45 cfg: _,
46 doc: _,
47 attrs: _,
48 visibility: _,
49 name,
50 colon_token: _,
51 ty,
52 } = self;
53 name.rust.to_tokens(tokens);
54 Token).to_tokens(tokens);
55 ty.to_tokens(tokens);
56 }
57}
58
59impl ToTokens for Ty1 {
60 fn to_tokens(&self, tokens: &mut TokenStream) {
61 let Ty1 {
62 name,
63 langle,
64 inner,
65 rangle,
66 } = self;
67 let span = name.span();
68 match name.to_string().as_str() {
69 "UniquePtr" | "SharedPtr" | "WeakPtr" | "CxxVector" => {
70 tokens.extend(quote_spanned!(span=> ::cxx::));
71 }
72 "Box" => {
73 tokens.extend(quote_spanned!(span=> ::cxx::alloc::boxed::));
74 }
75 "Vec" => {
76 tokens.extend(quote_spanned!(span=> ::cxx::alloc::vec::));
77 }
78 _ => {}
79 }
80 name.to_tokens(tokens);
81 langle.to_tokens(tokens);
82 inner.to_tokens(tokens);
83 rangle.to_tokens(tokens);
84 }
85}
86
87impl ToTokens for Ref {
88 fn to_tokens(&self, tokens: &mut TokenStream) {
89 let Ref {
90 pinned: _,
91 ampersand,
92 lifetime,
93 mutable: _,
94 inner,
95 pin_tokens,
96 mutability,
97 } = self;
98 if let Some((pin, langle, _rangle)) = pin_tokens {
99 tokens.extend(quote_spanned!(pin.span=> ::cxx::core::pin::Pin));
100 langle.to_tokens(tokens);
101 }
102 ampersand.to_tokens(tokens);
103 lifetime.to_tokens(tokens);
104 mutability.to_tokens(tokens);
105 inner.to_tokens(tokens);
106 if let Some((_pin, _langle, rangle)) = pin_tokens {
107 rangle.to_tokens(tokens);
108 }
109 }
110}
111
112impl ToTokens for Ptr {
113 fn to_tokens(&self, tokens: &mut TokenStream) {
114 let Ptr {
115 star,
116 mutable: _,
117 inner,
118 mutability,
119 constness,
120 } = self;
121 star.to_tokens(tokens);
122 mutability.to_tokens(tokens);
123 constness.to_tokens(tokens);
124 inner.to_tokens(tokens);
125 }
126}
127
128impl ToTokens for SliceRef {
129 fn to_tokens(&self, tokens: &mut TokenStream) {
130 let SliceRef {
131 ampersand,
132 lifetime,
133 mutable: _,
134 bracket,
135 inner,
136 mutability,
137 } = self;
138 ampersand.to_tokens(tokens);
139 lifetime.to_tokens(tokens);
140 mutability.to_tokens(tokens);
141 bracket.surround(tokens, |tokens| {
142 inner.to_tokens(tokens);
143 });
144 }
145}
146
147impl ToTokens for Array {
148 fn to_tokens(&self, tokens: &mut TokenStream) {
149 let Array {
150 bracket,
151 inner,
152 semi_token,
153 len: _,
154 len_token,
155 } = self;
156 bracket.surround(tokens, |tokens| {
157 inner.to_tokens(tokens);
158 semi_token.to_tokens(tokens);
159 len_token.to_tokens(tokens);
160 });
161 }
162}
163
164impl ToTokens for Atom {
165 fn to_tokens(&self, tokens: &mut TokenStream) {
166 Ident::new(self.as_ref(), Span::call_site()).to_tokens(tokens);
167 }
168}
169
170impl ToTokens for Derive {
171 fn to_tokens(&self, tokens: &mut TokenStream) {
172 Ident::new(self.what.as_ref(), self.span).to_tokens(tokens);
173 }
174}
175
176impl ToTokens for ExternType {
177 fn to_tokens(&self, tokens: &mut TokenStream) {
178 self.type_token.to_tokens(tokens);
180 self.name.rust.to_tokens(tokens);
181 self.generics.to_tokens(tokens);
182 }
183}
184
185impl ToTokens for TypeAlias {
186 fn to_tokens(&self, tokens: &mut TokenStream) {
187 self.type_token.to_tokens(tokens);
189 self.name.rust.to_tokens(tokens);
190 self.generics.to_tokens(tokens);
191 }
192}
193
194impl ToTokens for Struct {
195 fn to_tokens(&self, tokens: &mut TokenStream) {
196 self.struct_token.to_tokens(tokens);
198 self.name.rust.to_tokens(tokens);
199 self.generics.to_tokens(tokens);
200 }
201}
202
203impl ToTokens for Enum {
204 fn to_tokens(&self, tokens: &mut TokenStream) {
205 self.enum_token.to_tokens(tokens);
207 self.name.rust.to_tokens(tokens);
208 self.generics.to_tokens(tokens);
209 }
210}
211
212impl ToTokens for ExternFn {
213 fn to_tokens(&self, tokens: &mut TokenStream) {
214 self.unsafety.to_tokens(tokens);
216 self.sig.fn_token.to_tokens(tokens);
217 self.semi_token.to_tokens(tokens);
218 }
219}
220
221impl ToTokens for Impl {
222 fn to_tokens(&self, tokens: &mut TokenStream) {
223 let Impl {
224 cfg: _,
225 impl_token,
226 impl_generics,
227 negative: _,
228 ty,
229 ty_generics: _,
230 brace_token,
231 negative_token,
232 } = self;
233 impl_token.to_tokens(tokens);
234 impl_generics.to_tokens(tokens);
235 negative_token.to_tokens(tokens);
236 ty.to_tokens(tokens);
237 brace_token.surround(tokens, |_tokens| {});
238 }
239}
240
241impl ToTokens for Lifetimes {
242 fn to_tokens(&self, tokens: &mut TokenStream) {
243 let Lifetimes {
244 lt_token,
245 lifetimes,
246 gt_token,
247 } = self;
248 lt_token.to_tokens(tokens);
249 lifetimes.to_tokens(tokens);
250 gt_token.to_tokens(tokens);
251 }
252}
253
254impl ToTokens for Signature {
255 fn to_tokens(&self, tokens: &mut TokenStream) {
256 let Signature {
257 asyncness: _,
258 unsafety: _,
259 fn_token,
260 generics: _,
261 receiver: _,
262 args,
263 ret,
264 throws: _,
265 paren_token,
266 throws_tokens,
267 } = self;
268 fn_token.to_tokens(tokens);
269 paren_token.surround(tokens, |tokens| {
270 args.to_tokens(tokens);
271 });
272 if let Some(ret) = ret {
273 Token).to_tokens(tokens);
274 if let Some((result, langle, rangle)) = throws_tokens {
275 result.to_tokens(tokens);
276 langle.to_tokens(tokens);
277 ret.to_tokens(tokens);
278 rangle.to_tokens(tokens);
279 } else {
280 ret.to_tokens(tokens);
281 }
282 } else if let Some((result, langle, rangle)) = throws_tokens {
283 Token).to_tokens(tokens);
284 result.to_tokens(tokens);
285 langle.to_tokens(tokens);
286 token::Paren(langle.span).surround(tokens, |_| ());
287 rangle.to_tokens(tokens);
288 }
289 }
290}
291
292impl ToTokens for EnumRepr {
293 fn to_tokens(&self, tokens: &mut TokenStream) {
294 match self {
295 EnumRepr::Native { atom, repr_type: _ } => atom.to_tokens(tokens),
296 #[cfg(feature = "experimental-enum-variants-from-header")]
297 EnumRepr::Foreign { rust_type } => rust_type.to_tokens(tokens),
298 }
299 }
300}
301
302impl ToTokens for NamedType {
303 fn to_tokens(&self, tokens: &mut TokenStream) {
304 let NamedType { rust, generics } = self;
305 rust.to_tokens(tokens);
306 generics.to_tokens(tokens);
307 }
308}