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