occams-rpc-api-macros 0.3.0

The macro crate for razor-rpc. razor-rpc is a modular, pluggable RPC for high throughput scenario, supports various runtimes, with a low-level streaming interface, and high-level remote API call interface.
Documentation
use proc_macro::TokenStream;
use quote::quote;
use syn::{Item, parse_macro_input};

pub fn service_mux_struct(_attr: TokenStream, item: TokenStream) -> TokenStream {
    let item_struct = parse_macro_input!(item as Item);
    let (struct_name, fields) = match &item_struct {
        Item::Struct(item_struct) => (&item_struct.ident, &item_struct.fields),
        _ => panic!("The `service_mux_struct` attribute can only be applied to structs."),
    };

    let field_handlers = fields.iter().map(|field| {
        let field_name = field.ident.as_ref().unwrap();
        let field_type = &field.ty;
        quote! {
            <#field_type as razor_rpc::server::ServiceStatic<C>>::SERVICE_NAME => self.#field_name.serve(req).await,
        }
    });

    let expanded = quote! {
        impl<C: razor_rpc::Codec> razor_rpc::server::ServiceStatic <C> for #struct_name {
            const SERVICE_NAME: &'static str = "";
            fn serve(&self, req: razor_rpc::server::task::APIServerReq<C>) -> impl std::future::Future<Output = ()> + Send {
                async move {
                    match req.service.as_str() {
                        #(#field_handlers)*
                        _ => req.set_rpc_error(razor_rpc::error::RpcIntErr::Service),
                    }
                }
            }
        }
    };

    let final_code = quote! {
        #item_struct
        #expanded
    };

    TokenStream::from(final_code)
}