1use proc_macro2::Span;
2use syn::parse::{Error, Parse, ParseStream, Result};
3use syn::{Attribute, ItemImpl, ItemTrait, Token};
4
5pub struct Nothing;
6
7impl Parse for Nothing {
8 fn parse(_input: ParseStream) -> Result<Self> {
9 Ok(Nothing)
10 }
11}
12
13pub enum Item {
14 Trait(ItemTrait),
15 Impl(ItemImpl),
16}
17
18impl Parse for Item {
19 fn parse(input: ParseStream) -> Result<Self> {
20 let attrs = input.call(Attribute::parse_outer)?;
21 let mut lookahead = input.lookahead1();
22 if lookahead.peek(Token![unsafe]) {
23 let ahead = input.fork();
24 ahead.parse::<Token![unsafe]>()?;
25 lookahead = ahead.lookahead1();
26 }
27 if lookahead.peek(Token![pub]) || lookahead.peek(Token![trait]) {
28 let mut item: ItemTrait = input.parse()?;
29 item.attrs = attrs;
30 Ok(Item::Trait(item))
31 } else if lookahead.peek(Token![impl]) {
32 let mut item: ItemImpl = input.parse()?;
33 if item.trait_.is_none() {
34 return Err(Error::new(Span::call_site(), "expected a trait impl"));
35 }
36 item.attrs = attrs;
37 Ok(Item::Impl(item))
38 } else {
39 Err(lookahead.error())
40 }
41 }
42}