Andrew Walbran | d1b91c7 | 2020-08-11 17:12:08 +0100 | [diff] [blame] | 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 { |
| 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 | } |