sark-gen 0.8.1

Sark proc-macro generators
Documentation
#![allow(clippy::too_many_arguments)]

use proc_macro2::{Ident, TokenStream};
use quote::{ToTokens, format_ident, quote};

pub(crate) struct Runtime;

impl Runtime {
    pub(crate) fn build<StateTy: ToTokens>(
        name: &Ident,
        state_ty: &StateTy,
        params_ident: &Ident,
        headers_ident: &Ident,
        call_with_parts_try_expr: Option<&TokenStream>,
        borrowed_call_cfg: Option<(&Ident, &Ident)>,
        handler_sync: bool,
        is_stream: bool,
    ) -> TokenStream {
        if !handler_sync {
            return TokenStream::new();
        }
        let state_has_lifetime = quote!(#state_ty).to_string().contains("'state");
        let state_lt_use: TokenStream = if state_has_lifetime {
            quote!(<'state>)
        } else {
            TokenStream::new()
        };
        let state_outlives: TokenStream = if state_has_lifetime {
            quote!('state: 'a,)
        } else {
            TokenStream::new()
        };
        let borrowed_impl = if let Some((request_inner_ident, hidden_fn_ref)) = borrowed_call_cfg {
            let hidden_fn_sync = format_ident!("{}_sync", hidden_fn_ref);
            quote! {
                impl #state_lt_use sark::service::manifold::Route<#state_ty> for #name {
                    fn invoke<'req, 'a>(
                        &'a self,
                        params: <Self as sark::service::RouteSpec>::Params<'req>,
                        req: &sark::request::Ref<'req, <Self as sark::service::RouteSpec>::Headers<'req>>,
                        headers: <Self as sark::service::RouteSpec>::Headers<'req>,
                        parsed_body: <Self as sark::service::RouteSpec>::ParsedBody<'req>,
                        state: &'a #state_ty,
                    ) -> <Self as sark::service::RouteSpec>::Response<'req>
                    where
                        'req: 'a,
                        #state_outlives
                    {
                        let request = #request_inner_ident::<'req>::from_parts_ref(
                            params,
                            headers,
                            parsed_body,
                            req,
                        );
                        #hidden_fn_sync(request, state)
                    }
                }
            }
        } else {
            TokenStream::new()
        };
        let stream_impl = if is_stream && let Some(expr) = call_with_parts_try_expr {
            quote! {
                impl sark::service::manifold::StreamRoute<#state_ty> for #name {
                    fn invoke(
                        &self,
                        params: #params_ident,
                        req: sark::Request,
                        headers: #headers_ident,
                        parsed_body: <Self as sark::service::RouteSpec>::ParsedBody<'static>,
                        state: &#state_ty,
                    ) -> <Self as sark::service::RouteSpec>::Response<'static> {
                        #expr
                    }
                }
            }
        } else {
            TokenStream::new()
        };
        quote! {
            #borrowed_impl
            #stream_impl
        }
    }
}