use super::basic::BasicPredicate;
use super::field_predicate::{FieldPredicate, LookupOp};
use crate::cacheable::Field;
use std::any::Any;
use std::sync::Arc;
fn ascii_fold(value: &str) -> String {
value.to_ascii_lowercase()
}
impl<T: 'static, V: PartialEq + Send + Sync + 'static> Field<T, V> {
pub fn eq(&self, val: V) -> BasicPredicate<T> {
let extract = self.extract;
let val_arc: Arc<V> = Arc::new(val);
let val_for_eval = val_arc.clone();
let value: Arc<dyn Any + Send + Sync> = val_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::Eq,
value,
move |t| extract(t) == &*val_for_eval,
))
}
pub fn neq(&self, val: V) -> BasicPredicate<T> {
let extract = self.extract;
let val_arc: Arc<V> = Arc::new(val);
let val_for_eval = val_arc.clone();
let value: Arc<dyn Any + Send + Sync> = val_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::Neq,
value,
move |t| extract(t) != &*val_for_eval,
))
}
}
impl<T: 'static, V: PartialOrd + Send + Sync + 'static> Field<T, V> {
pub fn gt(&self, val: V) -> BasicPredicate<T> {
let extract = self.extract;
let val_arc: Arc<V> = Arc::new(val);
let val_for_eval = val_arc.clone();
let value: Arc<dyn Any + Send + Sync> = val_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::Gt,
value,
move |t| extract(t) > &*val_for_eval,
))
}
pub fn gte(&self, val: V) -> BasicPredicate<T> {
let extract = self.extract;
let val_arc: Arc<V> = Arc::new(val);
let val_for_eval = val_arc.clone();
let value: Arc<dyn Any + Send + Sync> = val_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::Gte,
value,
move |t| extract(t) >= &*val_for_eval,
))
}
pub fn lt(&self, val: V) -> BasicPredicate<T> {
let extract = self.extract;
let val_arc: Arc<V> = Arc::new(val);
let val_for_eval = val_arc.clone();
let value: Arc<dyn Any + Send + Sync> = val_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::Lt,
value,
move |t| extract(t) < &*val_for_eval,
))
}
pub fn lte(&self, val: V) -> BasicPredicate<T> {
let extract = self.extract;
let val_arc: Arc<V> = Arc::new(val);
let val_for_eval = val_arc.clone();
let value: Arc<dyn Any + Send + Sync> = val_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::Lte,
value,
move |t| extract(t) <= &*val_for_eval,
))
}
pub fn between(&self, low: V, high: V) -> BasicPredicate<T> {
let extract = self.extract;
let pair_arc: Arc<(V, V)> = Arc::new((low, high));
let pair_for_eval = pair_arc.clone();
let value: Arc<dyn Any + Send + Sync> = pair_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::Between,
value,
move |t| {
let v = extract(t);
v >= &pair_for_eval.0 && v <= &pair_for_eval.1
},
))
}
}
impl<T: 'static, V: PartialEq + Send + Sync + 'static> Field<T, V> {
pub fn in_(&self, vals: Vec<V>) -> BasicPredicate<T> {
let extract = self.extract;
let vec_arc: Arc<Vec<V>> = Arc::new(vals);
let vec_for_eval = vec_arc.clone();
let value: Arc<dyn Any + Send + Sync> = vec_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::In,
value,
move |t| {
let v = extract(t);
vec_for_eval.iter().any(|cand| cand == v)
},
))
}
pub fn not_in(&self, vals: Vec<V>) -> BasicPredicate<T> {
let extract = self.extract;
let vec_arc: Arc<Vec<V>> = Arc::new(vals);
let vec_for_eval = vec_arc.clone();
let value: Arc<dyn Any + Send + Sync> = vec_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::NotIn,
value,
move |t| {
let v = extract(t);
!vec_for_eval.iter().any(|cand| cand == v)
},
))
}
}
impl<T: 'static, U: Send + Sync + 'static> Field<T, Option<U>> {
pub fn is_null(&self) -> BasicPredicate<T> {
let extract = self.extract;
let value: Arc<dyn Any + Send + Sync> = Arc::new(());
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::IsNull,
value,
move |t| extract(t).is_none(),
))
}
pub fn is_not_null(&self) -> BasicPredicate<T> {
let extract = self.extract;
let value: Arc<dyn Any + Send + Sync> = Arc::new(());
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::IsNotNull,
value,
move |t| extract(t).is_some(),
))
}
}
pub struct PresentField<T, V> {
field: Field<T, Option<V>>,
}
impl<T, V> std::fmt::Debug for PresentField<T, V> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PresentField")
.field("name", &self.field.name)
.finish_non_exhaustive()
}
}
impl<T, V> Copy for PresentField<T, V> {}
impl<T, V> Clone for PresentField<T, V> {
fn clone(&self) -> Self {
*self
}
}
impl<T, V> Field<T, Option<V>> {
pub fn some(&self) -> PresentField<T, V> {
PresentField { field: *self }
}
}
impl<T: 'static, V: PartialEq + Send + Sync + 'static> PresentField<T, V> {
pub fn eq(&self, val: V) -> BasicPredicate<T> {
let extract = self.field.extract;
let val_arc: Arc<V> = Arc::new(val);
let val_for_eval = val_arc.clone();
let value: Arc<dyn Any + Send + Sync> = val_arc;
BasicPredicate::Field(FieldPredicate::new(
self.field.name,
LookupOp::Eq,
value,
move |t| extract(t).as_ref().is_some_and(|v| v == &*val_for_eval),
))
}
pub fn neq(&self, val: V) -> BasicPredicate<T> {
let extract = self.field.extract;
let val_arc: Arc<V> = Arc::new(val);
let val_for_eval = val_arc.clone();
let value: Arc<dyn Any + Send + Sync> = val_arc;
BasicPredicate::Field(FieldPredicate::new(
self.field.name,
LookupOp::Neq,
value,
move |t| extract(t).as_ref().is_some_and(|v| v != &*val_for_eval),
))
}
pub fn in_(&self, vals: Vec<V>) -> BasicPredicate<T> {
let extract = self.field.extract;
let vec_arc: Arc<Vec<V>> = Arc::new(vals);
let vec_for_eval = vec_arc.clone();
let value: Arc<dyn Any + Send + Sync> = vec_arc;
BasicPredicate::Field(FieldPredicate::new(
self.field.name,
LookupOp::In,
value,
move |t| {
extract(t)
.as_ref()
.is_some_and(|v| vec_for_eval.iter().any(|cand| cand == v))
},
))
}
pub fn not_in(&self, vals: Vec<V>) -> BasicPredicate<T> {
let extract = self.field.extract;
let vec_arc: Arc<Vec<V>> = Arc::new(vals);
let vec_for_eval = vec_arc.clone();
let value: Arc<dyn Any + Send + Sync> = vec_arc;
BasicPredicate::Field(FieldPredicate::new(
self.field.name,
LookupOp::NotIn,
value,
move |t| {
extract(t)
.as_ref()
.is_some_and(|v| !vec_for_eval.iter().any(|cand| cand == v))
},
))
}
}
impl<T: 'static, V: PartialOrd + Send + Sync + 'static> PresentField<T, V> {
pub fn gt(&self, val: V) -> BasicPredicate<T> {
let extract = self.field.extract;
let val_arc: Arc<V> = Arc::new(val);
let val_for_eval = val_arc.clone();
let value: Arc<dyn Any + Send + Sync> = val_arc;
BasicPredicate::Field(FieldPredicate::new(
self.field.name,
LookupOp::Gt,
value,
move |t| extract(t).as_ref().is_some_and(|v| v > &*val_for_eval),
))
}
pub fn gte(&self, val: V) -> BasicPredicate<T> {
let extract = self.field.extract;
let val_arc: Arc<V> = Arc::new(val);
let val_for_eval = val_arc.clone();
let value: Arc<dyn Any + Send + Sync> = val_arc;
BasicPredicate::Field(FieldPredicate::new(
self.field.name,
LookupOp::Gte,
value,
move |t| extract(t).as_ref().is_some_and(|v| v >= &*val_for_eval),
))
}
pub fn lt(&self, val: V) -> BasicPredicate<T> {
let extract = self.field.extract;
let val_arc: Arc<V> = Arc::new(val);
let val_for_eval = val_arc.clone();
let value: Arc<dyn Any + Send + Sync> = val_arc;
BasicPredicate::Field(FieldPredicate::new(
self.field.name,
LookupOp::Lt,
value,
move |t| extract(t).as_ref().is_some_and(|v| v < &*val_for_eval),
))
}
pub fn lte(&self, val: V) -> BasicPredicate<T> {
let extract = self.field.extract;
let val_arc: Arc<V> = Arc::new(val);
let val_for_eval = val_arc.clone();
let value: Arc<dyn Any + Send + Sync> = val_arc;
BasicPredicate::Field(FieldPredicate::new(
self.field.name,
LookupOp::Lte,
value,
move |t| extract(t).as_ref().is_some_and(|v| v <= &*val_for_eval),
))
}
pub fn between(&self, low: V, high: V) -> BasicPredicate<T> {
let extract = self.field.extract;
let pair_arc: Arc<(V, V)> = Arc::new((low, high));
let pair_for_eval = pair_arc.clone();
let value: Arc<dyn Any + Send + Sync> = pair_arc;
BasicPredicate::Field(FieldPredicate::new(
self.field.name,
LookupOp::Between,
value,
move |t| {
extract(t)
.as_ref()
.is_some_and(|v| v >= &pair_for_eval.0 && v <= &pair_for_eval.1)
},
))
}
}
impl<T: 'static> Field<T, String> {
pub fn contains(&self, needle: &str) -> BasicPredicate<T> {
let extract = self.extract;
let needle_arc: Arc<String> = Arc::new(needle.to_owned());
let needle_for_eval = needle_arc.clone();
let value: Arc<dyn Any + Send + Sync> = needle_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::Contains,
value,
move |t| extract(t).contains(needle_for_eval.as_str()),
))
}
pub fn icontains(&self, needle: &str) -> BasicPredicate<T> {
let extract = self.extract;
let needle_arc: Arc<String> = Arc::new(needle.to_owned());
let needle_lower = ascii_fold(needle);
let value: Arc<dyn Any + Send + Sync> = needle_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::IContains,
value,
move |t| ascii_fold(extract(t)).contains(needle_lower.as_str()),
))
}
pub fn starts_with(&self, prefix: &str) -> BasicPredicate<T> {
let extract = self.extract;
let prefix_arc: Arc<String> = Arc::new(prefix.to_owned());
let prefix_for_eval = prefix_arc.clone();
let value: Arc<dyn Any + Send + Sync> = prefix_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::StartsWith,
value,
move |t| extract(t).starts_with(prefix_for_eval.as_str()),
))
}
pub fn istarts_with(&self, prefix: &str) -> BasicPredicate<T> {
let extract = self.extract;
let prefix_arc: Arc<String> = Arc::new(prefix.to_owned());
let prefix_lower = ascii_fold(prefix);
let value: Arc<dyn Any + Send + Sync> = prefix_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::IStartsWith,
value,
move |t| ascii_fold(extract(t)).starts_with(prefix_lower.as_str()),
))
}
pub fn ends_with(&self, suffix: &str) -> BasicPredicate<T> {
let extract = self.extract;
let suffix_arc: Arc<String> = Arc::new(suffix.to_owned());
let suffix_for_eval = suffix_arc.clone();
let value: Arc<dyn Any + Send + Sync> = suffix_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::EndsWith,
value,
move |t| extract(t).ends_with(suffix_for_eval.as_str()),
))
}
pub fn iends_with(&self, suffix: &str) -> BasicPredicate<T> {
let extract = self.extract;
let suffix_arc: Arc<String> = Arc::new(suffix.to_owned());
let suffix_lower = ascii_fold(suffix);
let value: Arc<dyn Any + Send + Sync> = suffix_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::IEndsWith,
value,
move |t| ascii_fold(extract(t)).ends_with(suffix_lower.as_str()),
))
}
pub fn iexact(&self, val: &str) -> BasicPredicate<T> {
let extract = self.extract;
let val_arc: Arc<String> = Arc::new(val.to_owned());
let val_folded = ascii_fold(val);
let value: Arc<dyn Any + Send + Sync> = val_arc;
BasicPredicate::Field(FieldPredicate::new(
self.name,
LookupOp::IExact,
value,
move |t| ascii_fold(extract(t)) == val_folded,
))
}
}