1use convert_case::{Case, Casing};
2use proc_macro::TokenStream;
3use quote::{ToTokens, format_ident, quote};
4
5#[proc_macro_derive(Invoke)]
6pub fn into_extract(input: TokenStream) -> TokenStream {
7 let input = syn::parse_macro_input!(input as syn::ItemEnum);
8
9 let ident = &input.ident;
10 let match_arms = input.variants.iter().map(|variant| {
11 let module = variant
12 .ident
13 .to_token_stream()
14 .to_string()
15 .to_case(Case::Snake);
16 let module = format_ident!("{}", module);
17 quote! {
18 #variant => #module :: extract
19 }
20 });
21
22 let generated = quote! {
23 impl #ident {
24 fn invoke(self, input: &syn::DeriveInput, via: Option<syn::Type>) -> TokenStream {
25 use #ident :: *;
26 (match self {
27 #(#match_arms),*
28 })(input, via)
29 }
30 }
31 };
32
33 generated.into()
34}