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 (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); let name = &input.ident; let has_user = input .fields .iter() .find(|f| { if let Some(ref ident) = f.ident { ident == "user" } else { false } }) .is_some(); let (use_any, user_is_option_user) = if has_user { ( quote!( use ::std::any::Any; ), quote!( ::std::any::TypeId::of::<::std::option::Option>() == self.user.type_id() ), ) } else { (quote!(), quote!(false)) }; let output = quote!( impl #impl_generics #name #ty_generics #where_clause { pub fn has_optional_user(&self) -> bool { #use_any #user_is_option_user } } ); TokenStream::from(output) }