miko-macros 0.1.6

Macros for miko
Documentation
use proc_macro::TokenStream;
use proc_macro2::{Ident, Span};
use quote::quote;
use syn::{parse_quote, ItemFn, Stmt};
use crate::extractor::body::deal_with_body_attr;
use crate::extractor::path::deal_with_path_attr;
use crate::route::{build_register_expr, RouteAttr};
use crate::toolkit::exactors::build_struct_from_query;
use crate::toolkit::rout_arg::{FnArgResult, IntoFnArgs, RouteFnArg};

pub fn route_handler(args: RouteAttr, mut fn_item: ItemFn) -> TokenStream {
    let fn_name = fn_item.sig.ident.clone();
    // 自动返回值
    let sig = &mut fn_item.sig;
    if matches!(sig.output,syn::ReturnType::Default) {
        (*sig).output = parse_quote!(-> impl ::miko::handler::into_response::IntoResponse)
    }
    let mut inject_segs: Vec<Stmt> = Vec::new();
    let rfa = RouteFnArg::from_punctuated(&mut sig.inputs);
    let path_inputs = rfa.gen_fn_args(deal_with_path_attr);
    let body_inputs = rfa.gen_fn_args(deal_with_body_attr);
    let plain_inputs = rfa.gen_fn_args(|rfa| if rfa.mark.is_empty() { FnArgResult::Keep } else { FnArgResult::Remove });
    // 清空参数
    sig.inputs.clear();
    // 获取无修饰参数
    // 组装path
    sig.inputs.extend(path_inputs);
    // 构建 Query 结构体和解构提取器
    let q_struct_ident = Ident::new(&format!("__{}_QueryStruct", fn_name.to_string()), Span::call_site());
    // 重组Query
    let (q_struct, q_struct_exactor) = build_struct_from_query(&rfa, q_struct_ident);
    if q_struct.is_some() {
        sig.inputs.push(q_struct_exactor.unwrap());
    }
    // 组装plain_inputs
    sig.inputs.extend(plain_inputs);
    // 最后组装body
    sig.inputs.extend(body_inputs);
    // 展开
    let block = &fn_item.block.clone();
    let inventory_collect: Option<proc_macro2::TokenStream> = if cfg!(feature = "auto") {
        Some(build_register_expr(&args, &fn_name.clone()))
    } else {None};
    quote! {
    #q_struct

    #sig {
      #(#inject_segs)*
      #block
    }

    #inventory_collect

  }.into()
}