Skip to content

Commit

Permalink
Generic type filter
Browse files Browse the repository at this point in the history
* Add FilterTrait
* separate StringFilter
* implement FilterTrait for enumerations Filters
* implement FilterTrait for FilterType struct

Co-authored-by: Panagiotis Karatakis
  • Loading branch information
billy1624 authored Nov 10, 2022
1 parent 98065ea commit c49bd99
Show file tree
Hide file tree
Showing 4 changed files with 335 additions and 120 deletions.
51 changes: 51 additions & 0 deletions derive/src/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,56 @@ pub fn enum_filter_fn(ident: syn::Ident) -> TokenStream {
pub is_not_in: Option<Vec<#ident>>,
pub is_null: Option<bool>,
}

impl seaography::FilterTrait for #name {
type Ty = #ident;

fn eq(&self) -> Option<Self::Ty> {
self.eq.clone()
}
fn ne(&self) -> Option<Self::Ty> {
self.ne.clone()
}
fn gt(&self) -> Option<Self::Ty> {
self.gt.clone()
}
fn gte(&self) -> Option<Self::Ty> {
self.gte.clone()
}
fn lt(&self) -> Option<Self::Ty> {
self.lt.clone()
}
fn lte(&self) -> Option<Self::Ty> {
self.lte.clone()
}
fn is_in(&self) -> Option<Vec<Self::Ty>> {
self.is_in.clone()
}
fn is_not_in(&self) -> Option<Vec<Self::Ty>> {
self.is_not_in.clone()
}
fn is_null(&self) -> Option<bool> {
self.is_null
}
fn contains(&self) -> Option<String> {
panic!("contains not supported for enumerations")
}
fn starts_with(&self) -> Option<String> {
panic!("starts_with not supported for enumerations")
}
fn ends_with(&self) -> Option<String> {
panic!("ends_with not supported for enumerations")
}
fn like(&self) -> Option<String> {
panic!("like not supported for enumerations")
}
fn not_like(&self) -> Option<String> {
panic!("not_like not supported for enumerations")
}
}

impl seaography::FilterTypeTrait for #ident {
type Filter = #name;
}
}
}
69 changes: 12 additions & 57 deletions derive/src/filter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heck::{ToSnakeCase, ToUpperCamelCase};
use proc_macro2::TokenStream;
use quote::{format_ident, quote, ToTokens};
use quote::{format_ident, quote};

#[derive(Debug, Eq, PartialEq, bae::FromAttributes)]
pub struct SeaOrm {
Expand Down Expand Up @@ -47,54 +47,9 @@ pub fn filter_struct(
) -> Result<TokenStream, crate::error::Error> {
let fields: Vec<TokenStream> = fields
.iter()
.map(|(ident, ty)| {
let type_literal = ty.to_token_stream().to_string();

let default_filters = vec![
"String",
"i8",
"i16",
"i32",
"i64",
"u8",
"u16",
"u32",
"u64",
"f32",
"f64",
#[cfg(feature = "with-chrono")]
"Date",
#[cfg(feature = "with-chrono")]
"DateTime",
#[cfg(feature = "with-chrono")]
"DateTimeUtc",
#[cfg(feature = "with-chrono")]
"DateTimeWithTimeZone",
#[cfg(feature = "with-decimal")]
"Decimal",
#[cfg(feature = "with-json")]
"Json",
#[cfg(feature = "with-uuid")]
"Uuid",
"BinaryVector",
"bool",
];

let filter_item = if default_filters.contains(&type_literal.as_str())
|| type_literal.starts_with("Vec")
{
quote! {
seaography::TypeFilter<#ty>
}
} else {
let ident = format_ident!("{}EnumFilter", type_literal);
quote! {
crate::entities::sea_orm_active_enums::#ident
}
};

.map(|(ident, type_ident)| {
quote! {
#ident: Option<#filter_item>
#ident: Option<<#type_ident as seaography::FilterTypeTrait>::Filter>
}
})
.collect();
Expand Down Expand Up @@ -202,39 +157,39 @@ pub fn recursive_filter_fn(fields: &[IdentTypeTuple]) -> Result<TokenStream, cra

quote!{
if let Some(#column_name) = current_filter.#column_name {
if let Some(eq_value) = #column_name.eq {
if let Some(eq_value) = seaography::FilterTrait::eq(&#column_name) {
condition = condition.add(Column::#column_enum_name.eq(eq_value))
}

if let Some(ne_value) = #column_name.ne {
if let Some(ne_value) = seaography::FilterTrait::ne(&#column_name) {
condition = condition.add(Column::#column_enum_name.ne(ne_value))
}

if let Some(gt_value) = #column_name.gt {
if let Some(gt_value) = seaography::FilterTrait::gt(&#column_name) {
condition = condition.add(Column::#column_enum_name.gt(gt_value))
}

if let Some(gte_value) = #column_name.gte {
if let Some(gte_value) = seaography::FilterTrait::gte(&#column_name) {
condition = condition.add(Column::#column_enum_name.gte(gte_value))
}

if let Some(lt_value) = #column_name.lt {
if let Some(lt_value) = seaography::FilterTrait::lt(&#column_name) {
condition = condition.add(Column::#column_enum_name.lt(lt_value))
}

if let Some(lte_value) = #column_name.lte {
if let Some(lte_value) = seaography::FilterTrait::lte(&#column_name) {
condition = condition.add(Column::#column_enum_name.lte(lte_value))
}

if let Some(is_in_value) = #column_name.is_in {
if let Some(is_in_value) = seaography::FilterTrait::is_in(&#column_name) {
condition = condition.add(Column::#column_enum_name.is_in(is_in_value))
}

if let Some(is_not_in_value) = #column_name.is_not_in {
if let Some(is_not_in_value) = seaography::FilterTrait::is_not_in(&#column_name) {
condition = condition.add(Column::#column_enum_name.is_not_in(is_not_in_value))
}

if let Some(is_null_value) = #column_name.is_null {
if let Some(is_null_value) = seaography::FilterTrait::is_null(&#column_name) {
if is_null_value {
condition = condition.add(Column::#column_enum_name.is_null())
}
Expand Down
66 changes: 3 additions & 63 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,75 +135,15 @@ pub use itertools;
use itertools::Itertools;
pub use seaography_derive as macros;

pub mod type_filter;
pub use type_filter::{FilterTrait, FilterTypeTrait, TypeFilter};

#[derive(Debug, Clone, Copy, PartialEq, Eq, async_graphql::Enum)]
pub enum OrderByEnum {
Asc,
Desc,
}

pub type BinaryVector = Vec<u8>;

#[derive(Debug, Clone, async_graphql::InputObject)]
#[graphql(concrete(name = "StringFilter", params(String)))]
#[graphql(concrete(name = "TinyIntegerFilter", params(i8)))]
#[graphql(concrete(name = "SmallIntegerFilter", params(i16)))]
#[graphql(concrete(name = "IntegerFilter", params(i32)))]
#[graphql(concrete(name = "BigIntegerFilter", params(i64)))]
#[graphql(concrete(name = "TinyUnsignedFilter", params(u8)))]
#[graphql(concrete(name = "SmallUnsignedFilter", params(u16)))]
#[graphql(concrete(name = "UnsignedFilter", params(u32)))]
#[graphql(concrete(name = "BigUnsignedFilter", params(u64)))]
#[graphql(concrete(name = "FloatFilter", params(f32)))]
#[graphql(concrete(name = "DoubleFilter", params(f64)))]
#[cfg_attr(
feature = "with-json",
graphql(concrete(name = "JsonFilter", params(sea_orm::prelude::Json)))
)]
// TODO #[graphql(concrete(name = "DateFilter", params()))]
// TODO #[graphql(concrete(name = "TimeFilter", params()))]
#[cfg_attr(
feature = "with-chrono",
graphql(concrete(name = "DateFilter", params(sea_orm::prelude::Date)))
)]
#[cfg_attr(
feature = "with-chrono",
graphql(concrete(name = "DateTimeFilter", params(sea_orm::prelude::DateTime)))
)]
#[cfg_attr(
feature = "with-chrono",
graphql(concrete(name = "DateTimeUtcFilter", params(sea_orm::prelude::DateTimeUtc)))
)]
#[cfg_attr(
feature = "with-chrono",
graphql(concrete(
name = "DateTimeWithTimeZoneFilter",
params(sea_orm::prelude::DateTimeWithTimeZone)
))
)]
// TODO #[graphql(concrete(name = "TimestampFilter", params()))]
// TODO #[graphql(concrete(name = "TimestampWithTimeZoneFilter", params()))]
#[cfg_attr(
feature = "with-decimal",
graphql(concrete(name = "DecimalFilter", params(sea_orm::prelude::Decimal)))
)]
#[cfg_attr(
feature = "with-uuid",
graphql(concrete(name = "UuidFilter", params(sea_orm::prelude::Uuid)))
)]
#[graphql(concrete(name = "BinaryFilter", params(BinaryVector)))]
#[graphql(concrete(name = "BooleanFilter", params(bool)))]
pub struct TypeFilter<T: async_graphql::InputType> {
pub eq: Option<T>,
pub ne: Option<T>,
pub gt: Option<T>,
pub gte: Option<T>,
pub lt: Option<T>,
pub lte: Option<T>,
pub is_in: Option<Vec<T>>,
pub is_not_in: Option<Vec<T>>,
pub is_null: Option<bool>,
}

#[derive(Debug, async_graphql::InputObject)]
pub struct PageInput {
pub limit: u64,
Expand Down
Loading

0 comments on commit c49bd99

Please sign in to comment.