async_trait/
bound.rs

1use proc_macro2::{Ident, Span, TokenStream};
2use quote::{quote, ToTokens};
3use syn::punctuated::Punctuated;
4use syn::{Token, TypeParamBound};
5
6pub type Supertraits = Punctuated<TypeParamBound, Token![+]>;
7
8pub enum InferredBound {
9    Send,
10    Sync,
11}
12
13pub fn has_bound(supertraits: &Supertraits, bound: &InferredBound) -> bool {
14    for supertrait in supertraits {
15        if let TypeParamBound::Trait(supertrait) = supertrait {
16            if supertrait.path.is_ident(bound)
17                || supertrait.path.segments.len() == 3
18                    && (supertrait.path.segments[0].ident == "std"
19                        || supertrait.path.segments[0].ident == "core")
20                    && supertrait.path.segments[1].ident == "marker"
21                    && supertrait.path.segments[2].ident == *bound
22            {
23                return true;
24            }
25        }
26    }
27    false
28}
29
30impl InferredBound {
31    fn as_str(&self) -> &str {
32        match self {
33            InferredBound::Send => "Send",
34            InferredBound::Sync => "Sync",
35        }
36    }
37}
38
39impl ToTokens for InferredBound {
40    fn to_tokens(&self, tokens: &mut TokenStream) {
41        let ident = Ident::new(self.as_str(), Span::call_site());
42        quote!(::core::marker::#ident).to_tokens(tokens);
43    }
44}
45
46impl PartialEq<InferredBound> for Ident {
47    fn eq(&self, bound: &InferredBound) -> bool {
48        self == bound.as_str()
49    }
50}