fiddler_macros/
lib.rs

1//! Helper macro for developing fiddler modules
2//!
3//! Fiddler [`fiddler::config::Callback`] requires a return signature of `std::pin::Pin<Box<dyn core::future::Future<Output = Result<ExecutionType, Error>> + Send>>`
4//! This helper macro will accept a function signature of `Fn(conf: Value) -> Result<ExecutionType, Error>`and convert it
5//! to the async Bos::pin future that is needed to store as a type
6use proc_macro::TokenStream;
7use quote::{quote, ToTokens};
8use syn::{parse_macro_input, parse_str, ItemFn, ReturnType};
9
10#[proc_macro_attribute]
11pub fn fiddler_registration_func(_attr: TokenStream, input: TokenStream) -> TokenStream {
12    let func = parse_macro_input!(input as ItemFn);
13    let func_name = func.sig.ident.clone();
14    assert!(func.sig.asyncness.is_none(), "async not supported");
15    let func_starter = func.sig.clone().fn_token;
16    let inputs = func.sig.clone().inputs;
17    let return_type = parse_str::<ReturnType>("-> std::pin::Pin<Box<dyn core::future::Future<Output = Result<ExecutionType, Error>> + Send>>").unwrap();
18
19    let mut statements = proc_macro2::TokenStream::new();
20    for i in func.block.stmts {
21        statements.extend(i.to_token_stream());
22    }
23
24    quote! {
25        #func_starter
26        #func_name(#inputs) #return_type  {
27            Box::pin(async move {
28                #statements
29            })
30        }
31    }
32    .to_token_stream()
33    .into()
34}