async_trait/
parse.rs

1use proc_macro2::Span;
2use syn::parse::{Error, Parse, ParseStream, Result};
3use syn::{Attribute, ItemImpl, ItemTrait, Token};
4
5pub enum Item {
6    Trait(ItemTrait),
7    Impl(ItemImpl),
8}
9
10impl Parse for Item {
11    fn parse(input: ParseStream) -> Result<Self> {
12        let attrs = input.call(Attribute::parse_outer)?;
13        let mut lookahead = input.lookahead1();
14        if lookahead.peek(Token![unsafe]) {
15            let ahead = input.fork();
16            ahead.parse::<Token![unsafe]>()?;
17            lookahead = ahead.lookahead1();
18        }
19        if lookahead.peek(Token![pub]) || lookahead.peek(Token![trait]) {
20            let mut item: ItemTrait = input.parse()?;
21            item.attrs = attrs;
22            Ok(Item::Trait(item))
23        } else if lookahead.peek(Token![impl]) {
24            let mut item: ItemImpl = input.parse()?;
25            if item.trait_.is_none() {
26                return Err(Error::new(Span::call_site(), "expected a trait impl"));
27            }
28            item.attrs = attrs;
29            Ok(Item::Impl(item))
30        } else {
31            Err(lookahead.error())
32        }
33    }
34}