maybe-async 0.2.6

A procedure macro to unify SYNC and ASYNC implementation
Documentation
use proc_macro2::Span;
use syn::{
    parse::{Parse, ParseStream, Result},
    Attribute, Error, ItemFn, ItemImpl, ItemTrait, Token,
};

pub enum Item {
    Trait(ItemTrait),
    Impl(ItemImpl),
    Fn(ItemFn),
}
impl Parse for Item {
    fn parse(input: ParseStream) -> Result<Self> {
        let attrs = input.call(Attribute::parse_outer)?;
        let mut lookahead = input.lookahead1();
        if lookahead.peek(Token![unsafe]) {
            let ahead = input.fork();
            ahead.parse::<Token![unsafe]>()?;
            lookahead = ahead.lookahead1();
        }
        if lookahead.peek(Token![impl]) {
            let mut item: ItemImpl = input.parse()?;
            if item.trait_.is_none() {
                return Err(Error::new(Span::call_site(), "expected a trait impl"));
            }
            item.attrs = attrs;
            Ok(Item::Impl(item))
        } else if lookahead.peek(Token![pub])
            || lookahead.peek(Token![trait])
            || lookahead.peek(Token![fn])
            || lookahead.peek(Token![async])
        {
            if lookahead.peek(Token![pub]) {
                let ahead = input.fork();
                ahead.parse::<Token![pub]>()?;
                lookahead = ahead.lookahead1();
            }
            if lookahead.peek(Token![trait]) {
                let mut item: ItemTrait = input.parse()?;
                item.attrs = attrs;
                Ok(Item::Trait(item))
            } else {
                let mut item: ItemFn = input.parse()?;
                item.attrs = attrs;
                Ok(Item::Fn(item))
            }
        } else {
            Err(lookahead.error())
        }
    }
}