use proc_macro::TokenStream;
use quote::quote;
use syn::{Data, DeriveInput, Fields, parse_macro_input};
#[proc_macro_derive(Event)]
pub fn derive_event(input: TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let ident = input.ident;
let generics = input.generics;
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let expanded = quote! {
impl #impl_generics maiko::Event for #ident #ty_generics #where_clause {}
};
TokenStream::from(expanded)
}
#[proc_macro_derive(Label)]
pub fn derive_label(input: TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let ident = input.ident;
let generics = input.generics;
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let label_impl = match &input.data {
Data::Enum(data_enum) => {
let match_arms = data_enum.variants.iter().map(|variant| {
let variant_ident = &variant.ident;
let variant_name = variant_ident.to_string();
let pattern = match &variant.fields {
Fields::Unit => quote! { Self::#variant_ident },
Fields::Unnamed(_) => quote! { Self::#variant_ident(..) },
Fields::Named(_) => quote! { Self::#variant_ident { .. } },
};
quote! {
#pattern => ::std::borrow::Cow::Borrowed(#variant_name)
}
});
quote! {
fn label(&self) -> ::std::borrow::Cow<'static, str> {
match self {
#(#match_arms),*
}
}
}
}
_ => {
return syn::Error::new_spanned(ident, "Label can only be derived for enums")
.to_compile_error()
.into();
}
};
let expanded = quote! {
impl #impl_generics maiko::Label for #ident #ty_generics #where_clause {
#label_impl
}
};
TokenStream::from(expanded)
}
#[proc_macro_derive(SelfRouting)]
pub fn derive_self_routing(input: TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let ident = input.ident;
let generics = input.generics;
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let expanded = quote! {
impl #impl_generics maiko::Topic<#ident #ty_generics> for #ident #ty_generics #where_clause {
fn from_event(event: &Self) -> Self {
event.clone()
}
}
};
TokenStream::from(expanded)
}