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}
35