1 use proc_macro2::Span;
2 use syn::parse::{Error, Parse, ParseStream, Result};
3 use syn::Token;
4 
5 #[derive(Copy, Clone)]
6 pub struct Args {
7     pub local: bool,
8 }
9 
10 mod kw {
11     syn::custom_keyword!(Send);
12 }
13 
14 impl Parse for Args {
parse(input: ParseStream) -> Result<Self>15     fn parse(input: ParseStream) -> Result<Self> {
16         match try_parse(input) {
17             Ok(args) if input.is_empty() => Ok(args),
18             _ => Err(error()),
19         }
20     }
21 }
22 
try_parse(input: ParseStream) -> Result<Args>23 fn try_parse(input: ParseStream) -> Result<Args> {
24     if input.peek(Token![?]) {
25         input.parse::<Token![?]>()?;
26         input.parse::<kw::Send>()?;
27         Ok(Args { local: true })
28     } else {
29         Ok(Args { local: false })
30     }
31 }
32 
error() -> Error33 fn error() -> Error {
34     let msg = "expected #[async_trait] or #[async_trait(?Send)]";
35     Error::new(Span::call_site(), msg)
36 }
37