1 use proc_macro2::Span;
2 use syn::parse::{Error, Parse, ParseStream, Result};
3 use syn::{Attribute, ItemImpl, ItemTrait, Token};
4 
5 pub enum Item {
6     Trait(ItemTrait),
7     Impl(ItemImpl),
8 }
9 
10 impl Parse for Item {
parse(input: ParseStream) -> Result<Self>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 }
35