cxxbridge_macro/
generics.rs

1use crate::syntax::instantiate::NamedImplKey;
2use crate::syntax::resolve::Resolution;
3use crate::syntax::{Impl, Lifetimes};
4use proc_macro2::TokenStream;
5use quote::ToTokens;
6use syn::{Lifetime, Token};
7
8pub(crate) struct ImplGenerics<'a> {
9    explicit_impl: Option<&'a Impl>,
10    resolve: Resolution<'a>,
11}
12
13pub(crate) struct TyGenerics<'a> {
14    key: NamedImplKey<'a>,
15    explicit_impl: Option<&'a Impl>,
16    resolve: Resolution<'a>,
17}
18
19pub(crate) fn split_for_impl<'a>(
20    key: NamedImplKey<'a>,
21    explicit_impl: Option<&'a Impl>,
22    resolve: Resolution<'a>,
23) -> (ImplGenerics<'a>, TyGenerics<'a>) {
24    let impl_generics = ImplGenerics {
25        explicit_impl,
26        resolve,
27    };
28    let ty_generics = TyGenerics {
29        key,
30        explicit_impl,
31        resolve,
32    };
33    (impl_generics, ty_generics)
34}
35
36impl<'a> ToTokens for ImplGenerics<'a> {
37    fn to_tokens(&self, tokens: &mut TokenStream) {
38        if let Some(imp) = self.explicit_impl {
39            imp.impl_generics.to_tokens(tokens);
40        } else {
41            self.resolve.generics.to_tokens(tokens);
42        }
43    }
44}
45
46impl<'a> ToTokens for TyGenerics<'a> {
47    fn to_tokens(&self, tokens: &mut TokenStream) {
48        if let Some(imp) = self.explicit_impl {
49            imp.ty_generics.to_tokens(tokens);
50        } else if !self.resolve.generics.lifetimes.is_empty() {
51            let span = self.key.rust.span();
52            self.key
53                .lt_token
54                .unwrap_or_else(|| Token![<](span))
55                .to_tokens(tokens);
56            self.resolve.generics.lifetimes.to_tokens(tokens);
57            self.key
58                .gt_token
59                .unwrap_or_else(|| Token![>](span))
60                .to_tokens(tokens);
61        }
62    }
63}
64
65pub(crate) struct UnderscoreLifetimes<'a> {
66    generics: &'a Lifetimes,
67}
68
69impl Lifetimes {
70    pub(crate) fn to_underscore_lifetimes(&self) -> UnderscoreLifetimes {
71        UnderscoreLifetimes { generics: self }
72    }
73}
74
75impl<'a> ToTokens for UnderscoreLifetimes<'a> {
76    fn to_tokens(&self, tokens: &mut TokenStream) {
77        let Lifetimes {
78            lt_token,
79            lifetimes,
80            gt_token,
81        } = self.generics;
82        lt_token.to_tokens(tokens);
83        for pair in lifetimes.pairs() {
84            let (lifetime, punct) = pair.into_tuple();
85            let lifetime = Lifetime::new("'_", lifetime.span());
86            lifetime.to_tokens(tokens);
87            punct.to_tokens(tokens);
88        }
89        gt_token.to_tokens(tokens);
90    }
91}