    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    use proc_macro2::Span;
    use syn::parse::{Error, Parse, ParseStream, Result};
    use syn::Token;

    #[derive(Copy, Clone)]
    pub struct Args {
        pub local: bool,
    }

    mod kw {
        syn::custom_keyword!(Send);
    }

    impl Parse for Args {
        fn parse(input: ParseStream) -> Result<Self> {
            match try_parse(input) {
                Ok(args) if input.is_empty() => Ok(args),
                _ => Err(error()),
            }
        }
    }

    fn try_parse(input: ParseStream) -> Result<Args> {
        if input.peek(Token![?]) {
            input.parse::<Token![?]>()?;
            input.parse::<kw::Send>()?;
            Ok(Args { local: true })
        } else {
            Ok(Args { local: false })
        }
    }

    fn error() -> Error {
        let msg = "expected #[async_trait] or #[async_trait(?Send)]";
        Error::new(Span::call_site(), msg)
    }