operaton_task_worker_macros/
lib.rs1extern crate proc_macro;
6
7use proc_macro::TokenStream;
8use quote::{format_ident, quote};
9use syn::{parse_macro_input, ItemFn, Meta, Expr, Lit};
10use proc_macro_crate::{crate_name, FoundCrate};
11
12#[proc_macro_attribute]
25pub fn task_handler(attr: TokenStream, item: TokenStream) -> TokenStream {
26 let meta = parse_macro_input!(attr as Meta);
28 let input_fn = parse_macro_input!(item as ItemFn);
29
30 let name_value = match meta {
31 Meta::NameValue(nv) if nv.path.is_ident("name") => match nv.value {
32 Expr::Lit(expr_lit) => match expr_lit.lit {
33 Lit::Str(s) => s.value(),
34 _ => panic!("#[task_handler] expects name to be a string literal: name = \"...\""),
35 },
36 _ => panic!("#[task_handler] expects name to be a string literal: name = \"...\""),
37 },
38 _ => panic!("#[task_handler] requires syntax: #[task_handler(name = \"...\")]"),
39 };
40
41 let fn_ident = input_fn.sig.ident.clone();
42
43 let runtime_crate_ident = match crate_name("operaton-task-worker") {
45 Ok(FoundCrate::Itself) => format_ident!("operaton_task_worker"),
46 Ok(FoundCrate::Name(name)) => format_ident!("{}", name),
47 Err(_) => format_ident!("operaton_task_worker"),
48 };
49
50 let expanded = quote! {
52 #input_fn
53
54 const _: () = {
55 #runtime_crate_ident::inventory::submit! {
57 #runtime_crate_ident::registry::Handler {
58 name: #name_value,
59 func: #fn_ident,
60 }
61 }
62 };
63 };
64
65 TokenStream::from(expanded)
66}