use std::rc::Rc;
use crate::{
Expr, Lazy, Table, TableRow,
lower::{self, ord_rc::OrdRc},
value::{DbTyp, EqTyp},
};
pub trait IntoExpr<'column, S> {
type Typ: DbTyp;
fn into_expr(self) -> Expr<'column, S, Self::Typ>;
}
impl<'column, S, T: IntoExpr<'column, S, Typ = X>, X: EqTyp> IntoExpr<'column, S> for Option<T> {
type Typ = Option<X>;
fn into_expr(self) -> Expr<'column, S, Self::Typ> {
let this = self.map(|x| x.into_expr().inner);
Expr::new(this.unwrap_or_else(|| Rc::new(lower::Expr::Constant("NULL"))))
}
}
impl<'column, S> IntoExpr<'column, S> for String {
type Typ = String;
fn into_expr(self) -> Expr<'column, S, Self::Typ> {
Expr::adhoc(lower::Expr::Parameter(OrdRc::new(self)))
}
}
impl<'column, S> IntoExpr<'column, S> for &str {
type Typ = String;
fn into_expr(self) -> Expr<'column, S, Self::Typ> {
self.to_owned().into_expr()
}
}
impl<'column, S> IntoExpr<'column, S> for Vec<u8> {
type Typ = Vec<u8>;
fn into_expr(self) -> Expr<'column, S, Self::Typ> {
Expr::adhoc(lower::Expr::Parameter(OrdRc::new(self)))
}
}
impl<'column, S> IntoExpr<'column, S> for &[u8] {
type Typ = Vec<u8>;
fn into_expr(self) -> Expr<'column, S, Self::Typ> {
self.to_owned().into_expr()
}
}
impl<'column, S> IntoExpr<'column, S> for bool {
type Typ = bool;
fn into_expr(self) -> Expr<'column, S, Self::Typ> {
Expr::adhoc(lower::Expr::Parameter(OrdRc::new(self)))
}
}
impl<'column, S> IntoExpr<'column, S> for i64 {
type Typ = i64;
fn into_expr(self) -> Expr<'column, S, Self::Typ> {
Expr::adhoc(lower::Expr::Parameter(OrdRc::new(self)))
}
}
impl<'column, S> IntoExpr<'column, S> for f64 {
type Typ = f64;
fn into_expr(self) -> Expr<'column, S, Self::Typ> {
Expr::adhoc(lower::Expr::Parameter(OrdRc::new(self)))
}
}
#[cfg(feature = "jiff-02")]
impl<'column, S> IntoExpr<'column, S> for jiff::Timestamp {
type Typ = Self;
fn into_expr(self) -> Expr<'column, S, Self::Typ> {
Expr::adhoc(lower::Expr::Parameter(OrdRc::new(self.out_to_value())))
}
}
#[cfg(feature = "jiff-02")]
impl<'column, S> IntoExpr<'column, S> for jiff::civil::Date {
type Typ = Self;
fn into_expr(self) -> Expr<'column, S, Self::Typ> {
Expr::adhoc(lower::Expr::Parameter(OrdRc::new(self.out_to_value())))
}
}
impl<'column, S, T> IntoExpr<'column, S> for &T
where
T: IntoExpr<'column, S> + Clone,
{
type Typ = T::Typ;
fn into_expr(self) -> Expr<'column, S, Self::Typ> {
T::into_expr(self.clone())
}
}
impl<'column, T: Table> IntoExpr<'column, T::Schema> for TableRow<T> {
type Typ = Self;
fn into_expr(self) -> Expr<'static, T::Schema, Self::Typ> {
let idx = self.inner.idx;
Expr::adhoc(lower::Expr::Parameter(OrdRc::new(idx)))
}
}
impl<'column, T: Table> IntoExpr<'column, T::Schema> for Lazy<'_, T> {
type Typ = TableRow<T>;
fn into_expr(self) -> crate::Expr<'column, T::Schema, Self::Typ> {
self.id.into_expr()
}
}
impl<'column, S, T: DbTyp> IntoExpr<'column, S> for Expr<'column, S, T> {
type Typ = T;
fn into_expr(self) -> Expr<'column, S, Self::Typ> {
self
}
}