2023-06-13 22:56:15 +00:00
|
|
|
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();
|
|
|
|
|
2023-06-13 23:15:47 +00:00
|
|
|
let user_is_option_user = if has_user {
|
2023-06-13 22:56:15 +00:00
|
|
|
quote!(
|
2023-06-13 23:15:47 +00:00
|
|
|
&&::std::any::TypeId::of::<::std::option::Option<crate::User>>() == self.user.type_id()
|
2023-06-13 22:56:15 +00:00
|
|
|
)
|
|
|
|
} else {
|
2023-06-13 23:15:47 +00:00
|
|
|
quote!()
|
2023-06-13 22:56:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
let output = quote!(
|
|
|
|
impl crate::templates::OptionalOptionalUser for #name {
|
|
|
|
fn has_optional_user(&self) -> bool {
|
|
|
|
use ::std::any::Any;
|
2023-06-13 23:15:47 +00:00
|
|
|
#has_user #user_is_option_user
|
2023-06-13 22:56:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
TokenStream::from(output)
|
|
|
|
}
|