use async_graphql::dynamic::{InputObject, InputValue, TypeRef};
use sea_orm::{EntityTrait, Iterable};
use crate::{BuilderContext, EntityObjectBuilder, FilterTypesMapHelper};
pub struct FilterInputConfig {
pub type_name: crate::SimpleNamingFn,
}
impl std::default::Default for FilterInputConfig {
fn default() -> Self {
FilterInputConfig {
type_name: Box::new(|object_name: &str| -> String {
format!("{object_name}FilterInput")
}),
}
}
}
pub struct FilterInputBuilder {
pub context: &'static BuilderContext,
}
impl FilterInputBuilder {
pub fn type_name(&self, object_name: &str) -> String {
self.context.filter_input.type_name.as_ref()(object_name)
}
pub fn to_object<T>(&self) -> InputObject
where
T: EntityTrait,
<T as EntityTrait>::Model: Sync,
{
let filter_types_map_helper = FilterTypesMapHelper {
context: self.context,
};
let entity_object_builder = EntityObjectBuilder {
context: self.context,
};
let entity_name = entity_object_builder.type_name::<T>();
let filter_name = self.type_name(&entity_name);
let object = T::Column::iter().fold(InputObject::new(&filter_name), |object, column| {
match filter_types_map_helper.get_column_filter_input_value::<T>(&column) {
Some(field) => object.field(field),
None => object,
}
});
object
.field(InputValue::new("and", TypeRef::named_nn_list(&filter_name)))
.field(InputValue::new("or", TypeRef::named_nn_list(&filter_name)))
}
}