use crate::{BindValue, Param};
use super::{BoolExpr, BoolOp, FieldRef, IntoFieldRef, ValueExpr};
impl<T> FieldRef<T> {
#[inline]
pub fn expr(self) -> ValueExpr {
ValueExpr::field(*self.meta, self.qualifier)
}
pub fn op(self, op: &'static str, right: impl Into<ValueExpr>) -> ValueExpr {
self.expr().op(op, right)
}
pub fn predicate(self, op: &'static str, right: impl Into<ValueExpr>) -> BoolExpr {
self.expr().predicate(op, right)
}
pub fn not_predicate(self, op: &'static str, right: impl Into<ValueExpr>) -> BoolExpr {
self.expr().not_predicate(op, right)
}
#[inline]
pub fn is_null(self) -> BoolExpr {
BoolExpr::is_null_expr(self.expr(), false)
}
#[inline]
pub fn is_not_null(self) -> BoolExpr {
BoolExpr::is_null_expr(self.expr(), true)
}
pub fn in_subquery(self, query: impl Into<crate::Stmt>) -> BoolExpr {
BoolExpr::in_subquery(self.expr(), Box::new(query.into()), false)
}
pub fn not_in_subquery(self, query: impl Into<crate::Stmt>) -> BoolExpr {
BoolExpr::in_subquery(self.expr(), Box::new(query.into()), true)
}
pub fn eq_field<R>(self, right: R) -> BoolExpr
where
R: IntoFieldRef<T>,
{
self.compare_field(BoolOp::Eq, right)
}
pub fn ne_field<R>(self, right: R) -> BoolExpr
where
R: IntoFieldRef<T>,
{
self.compare_field(BoolOp::Ne, right)
}
pub fn gt_field<R>(self, right: R) -> BoolExpr
where
R: IntoFieldRef<T>,
{
self.compare_field(BoolOp::Gt, right)
}
pub fn gte_field<R>(self, right: R) -> BoolExpr
where
R: IntoFieldRef<T>,
{
self.compare_field(BoolOp::Gte, right)
}
pub fn lt_field<R>(self, right: R) -> BoolExpr
where
R: IntoFieldRef<T>,
{
self.compare_field(BoolOp::Lt, right)
}
pub fn lte_field<R>(self, right: R) -> BoolExpr
where
R: IntoFieldRef<T>,
{
self.compare_field(BoolOp::Lte, right)
}
pub fn is_distinct_from_field<R>(self, right: R) -> BoolExpr
where
R: IntoFieldRef<T>,
{
self.compare_field(BoolOp::IsDistinctFrom, right)
}
pub fn is_not_distinct_from_field<R>(self, right: R) -> BoolExpr
where
R: IntoFieldRef<T>,
{
self.compare_field(BoolOp::IsNotDistinctFrom, right)
}
fn compare_field<R>(self, op: BoolOp, right: R) -> BoolExpr
where
R: IntoFieldRef<T>,
{
BoolExpr::compare(self.expr(), op, right.into_field_ref().expr())
}
}
impl<T: BindValue> FieldRef<T> {
pub fn eq(self, value: impl Into<T>) -> BoolExpr {
self.compare(BoolOp::Eq, value)
}
pub fn ne(self, value: impl Into<T>) -> BoolExpr {
self.compare(BoolOp::Ne, value)
}
pub fn gt(self, value: impl Into<T>) -> BoolExpr {
self.compare(BoolOp::Gt, value)
}
pub fn gte(self, value: impl Into<T>) -> BoolExpr {
self.compare(BoolOp::Gte, value)
}
pub fn lt(self, value: impl Into<T>) -> BoolExpr {
self.compare(BoolOp::Lt, value)
}
pub fn lte(self, value: impl Into<T>) -> BoolExpr {
self.compare(BoolOp::Lte, value)
}
pub fn is_distinct_from(self, value: impl Into<T>) -> BoolExpr {
self.compare(BoolOp::IsDistinctFrom, value)
}
pub fn is_not_distinct_from(self, value: impl Into<T>) -> BoolExpr {
self.compare(BoolOp::IsNotDistinctFrom, value)
}
pub fn in_list(self, values: impl IntoIterator<Item = impl Into<T>>) -> BoolExpr {
self.list_predicate(values, false)
}
pub fn not_in(self, values: impl IntoIterator<Item = impl Into<T>>) -> BoolExpr {
self.list_predicate(values, true)
}
pub fn between(self, low: impl Into<T>, high: impl Into<T>) -> BoolExpr {
self.between_predicate(low, high, false)
}
pub fn not_between(self, low: impl Into<T>, high: impl Into<T>) -> BoolExpr {
self.between_predicate(low, high, true)
}
fn compare(self, op: BoolOp, value: impl Into<T>) -> BoolExpr {
BoolExpr::compare(
self.expr(),
op,
ValueExpr::Param(Param::typed(value.into())),
)
}
fn list_predicate(
self,
values: impl IntoIterator<Item = impl Into<T>>,
negated: bool,
) -> BoolExpr {
let values = values
.into_iter()
.map(|value| ValueExpr::Param(Param::typed(value.into())))
.collect::<Vec<_>>();
BoolExpr::in_list(self.expr(), values, negated)
}
fn between_predicate(self, low: impl Into<T>, high: impl Into<T>, negated: bool) -> BoolExpr {
BoolExpr::between(
self.expr(),
ValueExpr::Param(Param::typed(low.into())),
ValueExpr::Param(Param::typed(high.into())),
negated,
)
}
}