inherent/
parse.rs

1use proc_macro2::{Span, TokenStream};
2use quote::ToTokens;
3use syn::parse::{Error, Parse, ParseStream, Result};
4use syn::token::Brace;
5use syn::{Attribute, Generics, ImplItem, ItemImpl, Path, Token, Type};
6
7#[derive(Clone)]
8pub struct TraitImpl {
9    pub attrs: Vec<Attribute>,
10    pub defaultness: Option<Token![default]>,
11    pub unsafety: Option<Token![unsafe]>,
12    pub impl_token: Token![impl],
13    pub generics: Generics,
14    pub trait_: Path,
15    pub for_token: Token![for],
16    pub self_ty: Type,
17    pub brace_token: Brace,
18    pub items: Vec<ImplItem>,
19}
20
21impl Parse for TraitImpl {
22    fn parse(input: ParseStream) -> Result<Self> {
23        let imp: ItemImpl = input.parse()?;
24
25        let (trait_, for_token) = match imp.trait_ {
26            Some((_bang_token, trait_, for_token)) => (trait_, for_token),
27            None => {
28                return Err(Error::new(
29                    Span::call_site(),
30                    "must be placed on a trait impl",
31                ))
32            }
33        };
34
35        Ok(TraitImpl {
36            attrs: imp.attrs,
37            defaultness: imp.defaultness,
38            unsafety: imp.unsafety,
39            impl_token: imp.impl_token,
40            generics: imp.generics,
41            trait_,
42            for_token,
43            self_ty: *imp.self_ty,
44            brace_token: imp.brace_token,
45            items: imp.items,
46        })
47    }
48}
49
50impl ToTokens for TraitImpl {
51    fn to_tokens(&self, tokens: &mut TokenStream) {
52        let imp = self.clone();
53
54        ItemImpl::to_tokens(
55            &ItemImpl {
56                attrs: imp.attrs,
57                defaultness: imp.defaultness,
58                unsafety: imp.unsafety,
59                impl_token: imp.impl_token,
60                generics: imp.generics,
61                trait_: Some((None, imp.trait_, imp.for_token)),
62                self_ty: Box::new(imp.self_ty),
63                brace_token: imp.brace_token,
64                items: imp.items,
65            },
66            tokens,
67        );
68    }
69}