guinea-macros 0.26.0

guinea's macros: actor!, feature!, #[handler], routes! and the backends' #[page]
Documentation
use proc_macro2::TokenStream;
use quote::quote;
use syn::DeriveInput;

use crate::handler::guinea_core_crate_path;

pub(crate) fn derive_request(input: DeriveInput) -> TokenStream {
    let mut reply: Option<syn::Type> = None;

    for attr in input.attrs.iter().filter(|attr| attr.path().is_ident("request")) {
        let parsed = attr.parse_nested_meta(|meta| {
            if meta.path.is_ident("reply") {
                if reply.is_some() {
                    return Err(meta.error("a request has one reply type"));
                }
                reply = Some(meta.value()?.parse()?);
                Ok(())
            } else {
                Err(meta.error("`request` takes `reply = Type`"))
            }
        });
        if let Err(error) = parsed {
            return error.to_compile_error();
        }
    }

    let Some(reply) = reply else {
        return syn::Error::new(
            input.ident.span(),
            "say what answers it: `#[request(reply = Type)]`",
        )
        .to_compile_error();
    };

    let gc = guinea_core_crate_path();
    let name = &input.ident;
    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();

    quote! {
        impl #impl_generics #gc::actor::event_bus::rpc::RpcCall for #name #ty_generics #where_clause {
            type Response = #reply;
        }
    }
}