nan_serve_dal_tx_impl/
lib.rs

1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use quote::quote;
5use syn::{
6    parse_macro_input, parse::Parse, parse::ParseStream,
7    ItemFn, Ident, Token, Result
8};
9
10
11struct ImplementTraitArgs {
12    struct_name: Ident,
13    trait_name: Ident,
14    fn_name: Ident,
15}
16
17impl Parse for ImplementTraitArgs {
18    fn parse(input: ParseStream) -> Result<Self> {
19        let struct_name: Ident = input.parse()?;
20        input.parse::<Token![,]>()?;
21        let trait_name: Ident = input.parse()?;
22        input.parse::<Token![,]>()?;
23        let fn_name: Ident = input.parse()?;
24        Ok(Self {
25            struct_name,
26            trait_name,
27            fn_name,
28        })
29    }
30}
31
32#[proc_macro_attribute]
33pub fn impl_transaction(attr: TokenStream, item: TokenStream) -> TokenStream {
34    // Parse the attribute arguments
35    let ImplementTraitArgs {
36        struct_name,
37        trait_name,
38        fn_name,
39    } = parse_macro_input!(attr as ImplementTraitArgs);
40
41    // Parse the input function
42    let input_fn = parse_macro_input!(item as ItemFn);
43
44    // Extract function components
45    let fn_inputs = &input_fn.sig.inputs;
46    let fn_body = &input_fn.block;
47
48    // Extract the function signature generics is there are any
49    let fn_generics = &input_fn.sig.generics;
50
51    let fn_output = match &input_fn.sig.output {
52        syn::ReturnType::Type(_, ty) => ty.as_ref(),
53        syn::ReturnType::Default => {
54            panic!("Function must have a return type.")
55        }
56    };
57
58    // Generate the expanded code
59    let expanded = quote! {
60        impl #trait_name for #struct_name {
61            fn #fn_name #fn_generics (#fn_inputs) -> impl std::future::Future<Output = #fn_output> + Send {
62                async move #fn_body
63            }
64        }
65    };
66    TokenStream::from(expanded)
67}