procmeta_core/
derive_input_context.rs1use proc_macro2::{Ident, TokenStream};
2use quote::quote;
3use syn::Result;
4use syn::{DeriveInput, ImplGenerics, TypeGenerics, WhereClause};
5
6pub struct DeriveInputContext<'a> {
7 pub input: &'a DeriveInput,
8 pub impl_generics: ImplGenerics<'a>,
9 pub ty_generics: TypeGenerics<'a>,
10 pub where_clause: Option<&'a WhereClause>,
11 pub trait_ty: Option<Ident>,
12 pub target_ty: Ident,
13}
14
15impl<'a> DeriveInputContext<'a> {
16 pub fn new(input: &'a DeriveInput, trait_ty: Option<Ident>, target_ty: Ident) -> Self {
17 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
18 Self {
19 input,
20 impl_generics,
21 ty_generics,
22 where_clause,
23 trait_ty,
24 target_ty,
25 }
26 }
27
28 pub fn impl_token(
29 self,
30 block_fn: impl Fn(&DeriveInputContext<'a>) -> Result<TokenStream>,
31 ) -> TokenStream {
32 let impl_generics = &self.impl_generics;
33 let ty_generics = &self.ty_generics;
34 let where_clause = &self.where_clause;
35 let block = block_fn(&self).unwrap_or_else(|err| err.into_compile_error());
36 let target_ty = &self.target_ty;
37 match self.trait_ty {
38 Some(trait_ty) => {
39 quote! {
40 impl #impl_generics #trait_ty for #target_ty #ty_generics #where_clause {
41 #block
42 }
43 }
44 }
45 None => {
46 quote! {
47 impl #impl_generics #target_ty #ty_generics #where_clause {
48 #block
49 }
50 }
51 }
52 }
53 }
54}