43 lines
1.2 KiB
Rust
43 lines
1.2 KiB
Rust
use proc_macro::TokenStream;
|
|
use syn::{spanned::Spanned, Data};
|
|
|
|
/// Macro to allow Recordable to be implemented on an enum by dispatching over each variant.
|
|
#[proc_macro_derive(Recordable)]
|
|
pub fn extract(input: TokenStream) -> TokenStream {
|
|
let ast = syn::parse_macro_input!(input);
|
|
|
|
impl_recordable(&ast)
|
|
}
|
|
|
|
fn impl_recordable(ast: &syn::DeriveInput) -> TokenStream {
|
|
let name = &ast.ident;
|
|
|
|
match &ast.data {
|
|
Data::Enum(en) => {
|
|
let extracted = en.variants.iter().map(|var| {
|
|
let ident = &var.ident;
|
|
|
|
quote::quote_spanned! {var.span()=>
|
|
Self::#ident (opt) => opt.run(ctx).await?
|
|
}
|
|
});
|
|
|
|
TokenStream::from(quote::quote! {
|
|
impl Recordable for #name {
|
|
async fn run(self, ctx: crate::Context<'_>) -> Result<(), crate::Error> {
|
|
match self {
|
|
#(#extracted,)*
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
_ => {
|
|
panic!("Only enums can derive Recordable");
|
|
}
|
|
}
|
|
}
|