use quote::format_ident;
use syn::{
parse::{Parse, ParseBuffer},
Ident, Path, Token,
};
pub struct Handler {
paths: Vec<Path>,
commands: Vec<Ident>,
wrappers: Vec<Path>,
}
impl Parse for Handler {
fn parse(input: &ParseBuffer<'_>) -> syn::Result<Self> {
let paths = input.parse_terminated::<Path, Token![,]>(Path::parse)?;
let (commands, wrappers) = paths
.iter()
.map(|path| {
let mut wrapper = path.clone();
let last = super::path_to_command(&mut wrapper);
let command = last.ident.clone();
last.ident = super::format_command_wrapper(&command);
(command, wrapper)
})
.unzip();
Ok(Self {
paths: paths.into_iter().collect(), commands,
wrappers,
})
}
}
impl From<Handler> for proc_macro::TokenStream {
fn from(
Handler {
paths,
commands,
wrappers,
}: Handler,
) -> Self {
let cmd = format_ident!("__tauri_cmd__");
let invoke = format_ident!("__tauri_invoke__");
quote::quote!(move |#invoke| {
let #cmd = #invoke.message.command();
match #cmd {
#(stringify!(#commands) => #wrappers!(#paths, #invoke),)*
_ => {
#invoke.resolver.reject(format!("command {} not found", #cmd))
},
}
})
.into()
}
}