cxxbridge_macro/syntax/
tokens.rs

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![:](name.rust.span()).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        // Notional token range for error reporting purposes.
179        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        // Notional token range for error reporting purposes.
188        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        // Notional token range for error reporting purposes.
197        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        // Notional token range for error reporting purposes.
206        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        // Notional token range for error reporting purposes.
215        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![->](paren_token.span.join()).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![->](paren_token.span.join()).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}