maybe_async/
parse.rs

1use proc_macro2::Span;
2use syn::{
3    parse::{discouraged::Speculative, Parse, ParseStream, Result},
4    Attribute, Error, ItemFn, ItemImpl, ItemStatic, ItemTrait,
5};
6
7pub enum Item {
8    Trait(ItemTrait),
9    Impl(ItemImpl),
10    Fn(ItemFn),
11    Static(ItemStatic),
12}
13
14macro_rules! fork {
15    ($fork:ident = $input:ident) => {{
16        $fork = $input.fork();
17        &$fork
18    }};
19}
20
21impl Parse for Item {
22    fn parse(input: ParseStream) -> Result<Self> {
23        let attrs = input.call(Attribute::parse_outer)?;
24        let mut fork;
25        let item = if let Ok(mut item) = fork!(fork = input).parse::<ItemImpl>() {
26            item.attrs = attrs;
27            Item::Impl(item)
28        } else if let Ok(mut item) = fork!(fork = input).parse::<ItemTrait>() {
29            item.attrs = attrs;
30            Item::Trait(item)
31        } else if let Ok(mut item) = fork!(fork = input).parse::<ItemFn>() {
32            item.attrs = attrs;
33            Item::Fn(item)
34        } else if let Ok(mut item) = fork!(fork = input).parse::<ItemStatic>() {
35            item.attrs = attrs;
36            Item::Static(item)
37        } else {
38            return Err(Error::new(Span::call_site(), "expected impl, trait or fn"));
39        };
40        input.advance_to(&fork);
41        Ok(item)
42    }
43}