use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use super::parse::{EntityDef, FilterType};
use crate::utils::marker;
pub fn generate(entity: &EntityDef) -> TokenStream {
if !entity.has_filters() {
return TokenStream::new();
}
let vis = &entity.vis;
let query_name = entity.ident_with("", "Query");
let filter_fields = entity.filter_fields();
let field_defs: Vec<TokenStream> = filter_fields
.iter()
.flat_map(|f| {
let name = f.name();
let ty = f.ty();
let filter = f.filter();
match filter.filter_type {
FilterType::Eq | FilterType::Like => {
vec![quote! { pub #name: Option<#ty> }]
}
FilterType::Range => {
let from_name = format_ident!("{}_from", name);
let to_name = format_ident!("{}_to", name);
vec![
quote! { pub #from_name: Option<#ty> },
quote! { pub #to_name: Option<#ty> },
]
}
FilterType::None => vec![]
}
})
.collect();
let marker = marker::generated();
let filter_name = entity.ident_with("", "Filter");
quote! {
#marker
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "api", derive(utoipa::ToSchema))]
#vis struct #query_name {
#(#field_defs,)*
pub limit: Option<i64>,
pub offset: Option<i64>,
}
#vis type #filter_name = #query_name;
}
}