| use proc_macro2::Span; |
| use syn::parse::{Error, Parse, ParseStream, Result}; |
| use syn::{Attribute, ItemImpl, ItemTrait, Token}; |
| |
| pub enum Item { |
| Trait(ItemTrait), |
| Impl(ItemImpl), |
| } |
| |
| 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![pub]) || lookahead.peek(Token![trait]) { |
| let mut item: ItemTrait = input.parse()?; |
| item.attrs = attrs; |
| Ok(Item::Trait(item)) |
| } else 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 { |
| Err(lookahead.error()) |
| } |
| } |
| } |