use vantage_expressions::traits::expressive::ExpressiveEnum;
use vantage_expressions::{Expression, Expressive};
pub trait Operation<T>: Expressive<T> {
fn eq(&self, value: impl Expressive<T>) -> Expression<T> {
Expression::new(
"{} = {}",
vec![
ExpressiveEnum::Nested(self.expr()),
ExpressiveEnum::Nested(value.expr()),
],
)
}
fn ne(&self, value: impl Expressive<T>) -> Expression<T> {
Expression::new(
"{} != {}",
vec![
ExpressiveEnum::Nested(self.expr()),
ExpressiveEnum::Nested(value.expr()),
],
)
}
fn gt(&self, value: impl Expressive<T>) -> Expression<T> {
Expression::new(
"{} > {}",
vec![
ExpressiveEnum::Nested(self.expr()),
ExpressiveEnum::Nested(value.expr()),
],
)
}
fn gte(&self, value: impl Expressive<T>) -> Expression<T> {
Expression::new(
"{} >= {}",
vec![
ExpressiveEnum::Nested(self.expr()),
ExpressiveEnum::Nested(value.expr()),
],
)
}
fn lt(&self, value: impl Expressive<T>) -> Expression<T> {
Expression::new(
"{} < {}",
vec![
ExpressiveEnum::Nested(self.expr()),
ExpressiveEnum::Nested(value.expr()),
],
)
}
fn lte(&self, value: impl Expressive<T>) -> Expression<T> {
Expression::new(
"{} <= {}",
vec![
ExpressiveEnum::Nested(self.expr()),
ExpressiveEnum::Nested(value.expr()),
],
)
}
fn in_(&self, values: impl Expressive<T>) -> Expression<T> {
Expression::new(
"{} IN ({})",
vec![
ExpressiveEnum::Nested(self.expr()),
ExpressiveEnum::Nested(values.expr()),
],
)
}
fn in_list<V: Into<T> + Clone>(&self, values: &[V]) -> Expression<T> {
let params: Vec<Expression<T>> = values
.iter()
.map(|v| Expression::new("{}", vec![ExpressiveEnum::Scalar(v.clone().into())]))
.collect();
Expression::new(
"{} IN ({})",
vec![
ExpressiveEnum::Nested(self.expr()),
ExpressiveEnum::Nested(Expression::from_vec(params, ", ")),
],
)
}
fn cast(&self, type_name: &str) -> Expression<T> {
Expression::new(
format!("CAST({{}} AS {type_name})"),
vec![ExpressiveEnum::Nested(self.expr())],
)
}
fn is_null(&self) -> Expression<T> {
Expression::new("{} IS NULL", vec![ExpressiveEnum::Nested(self.expr())])
}
fn is_not_null(&self) -> Expression<T> {
Expression::new("{} IS NOT NULL", vec![ExpressiveEnum::Nested(self.expr())])
}
}
impl<T, S: Expressive<T>> Operation<T> for S {}
#[cfg(test)]
mod tests {
use super::*;
use crate::column::core::Column;
#[test]
fn test_is_null() {
let deleted_at = Column::<String>::new("deleted_at");
let expr = deleted_at.is_null();
assert_eq!(expr.preview(), "deleted_at IS NULL");
}
#[test]
fn test_is_not_null() {
let email = Column::<String>::new("email");
let expr = email.is_not_null();
assert_eq!(expr.preview(), "email IS NOT NULL");
}
}