use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, ItemStruct}; #[proc_macro_derive(OptionalOptionalUser)] pub fn derive_optional_optional_user(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as ItemStruct); let name = &input.ident; let has_user = input .fields .iter() .find(|f| { if let Some(ident) = f.ident.clone() { ident == "user" } else { false } }) .is_some(); let has_option = if has_user { quote!( ::std::any::TypeId::of::<::std::option::Option>() == self.user.type_id() ) } else { quote!(false) }; let output = quote!( impl crate::templates::OptionalOptionalUser for #name { fn has_optional_user(&self) -> bool { use ::std::any::Any; #has_user && #has_option } } ); TokenStream::from(output) }