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>23fn 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() -> Error33fn error() -> Error { 34 let msg = "expected #[async_trait] or #[async_trait(?Send)]"; 35 Error::new(Span::call_site(), msg) 36 } 37