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