extern crate proc_macro;
use proc_macro::TokenStream;
use quote::{format_ident, quote};
use syn::{parse_macro_input, ItemFn, Meta, Expr, Lit};
use proc_macro_crate::{crate_name, FoundCrate};
#[proc_macro_attribute]
pub fn task_handler(attr: TokenStream, item: TokenStream) -> TokenStream {
let meta = parse_macro_input!(attr as Meta);
let input_fn = parse_macro_input!(item as ItemFn);
let name_value = match meta {
Meta::NameValue(nv) if nv.path.is_ident("name") => match nv.value {
Expr::Lit(expr_lit) => match expr_lit.lit {
Lit::Str(s) => s.value(),
_ => panic!("#[task_handler] expects name to be a string literal: name = \"...\""),
},
_ => panic!("#[task_handler] expects name to be a string literal: name = \"...\""),
},
_ => panic!("#[task_handler] requires syntax: #[task_handler(name = \"...\")]"),
};
let fn_ident = input_fn.sig.ident.clone();
let runtime_crate_ident = match crate_name("operaton-task-worker") {
Ok(FoundCrate::Itself) => format_ident!("operaton_task_worker"),
Ok(FoundCrate::Name(name)) => format_ident!("{}", name),
Err(_) => format_ident!("operaton_task_worker"),
};
let expanded = quote! {
#input_fn
const _: () = {
#runtime_crate_ident::inventory::submit! {
#runtime_crate_ident::registry::Handler {
name: #name_value,
func: #fn_ident,
}
}
};
};
TokenStream::from(expanded)
}