use crate::toolkit::rout_arg::RouteFnArg;
use proc_macro2::Ident;
use quote::quote;
use syn::{FnArg, ItemStruct, parse_quote};
pub fn build_struct_from_query(
rfa: &Vec<RouteFnArg>,
struct_name: Ident,
) -> (Option<ItemStruct>, Option<FnArg>) {
let mut fields = Vec::new();
let mut idents = Vec::new();
for rfa in rfa {
if rfa.mark.contains_key("query") {
let name = &rfa.ident;
let ty = rfa.ty.clone();
idents.push(name.clone());
let desc_attr = extract_desc_attr(&rfa.attrs);
fields.push(quote! {
#desc_attr
pub #name: #ty
})
}
}
if !fields.is_empty() {
#[cfg(feature = "utoipa")]
let derives = quote! {
#[derive(::miko::serde::Deserialize, ::miko::utoipa::IntoParams)]
};
#[cfg(not(feature = "utoipa"))]
let derives = quote! {
#[derive(::miko::serde::Deserialize)]
};
let q_struct: ItemStruct = parse_quote! {
#derives
struct #struct_name {
#(#fields),*
}
};
let stmt: FnArg = parse_quote! {
::miko::extractor::Query(#struct_name { #(#idents),* }): ::miko::extractor::Query<#struct_name>
};
(Some(q_struct), Some(stmt))
} else {
(None, None)
}
}
fn extract_desc_attr(attrs: &[syn::Attribute]) -> proc_macro2::TokenStream {
#[cfg(feature = "utoipa")]
{
for attr in attrs {
if attr.path().is_ident("desc")
&& let Ok(lit) = attr.parse_args::<syn::LitStr>()
{
return quote! {
#[schema(description = #lit)]
};
}
}
}
#[cfg(not(feature = "utoipa"))]
let _ = attrs;
quote! {}
}