use crate::{IntoExpr, IntoSelect, Table, TableRow, optional, select::Select, value::EqTyp};
pub trait FromExpr<S, From>: 'static + Sized {
fn from_expr<'columns>(
col: impl IntoExpr<'columns, S, Typ = From>,
) -> Select<'columns, S, Self>;
}
macro_rules! from_expr {
($typ:ty) => {
impl<S> FromExpr<S, $typ> for $typ {
fn from_expr<'columns>(
col: impl IntoExpr<'columns, S, Typ = $typ>,
) -> Select<'columns, S, Self> {
col.into_expr().into_select()
}
}
};
}
from_expr! {String}
from_expr! {Vec<u8>}
from_expr! {i64}
from_expr! {f64}
from_expr! {bool}
#[cfg(feature = "jiff-02")]
from_expr! {jiff::Timestamp}
#[cfg(feature = "jiff-02")]
from_expr! {jiff::civil::Date}
impl<T: Table> FromExpr<T::Schema, TableRow<T>> for TableRow<T> {
fn from_expr<'columns>(
col: impl IntoExpr<'columns, T::Schema, Typ = TableRow<T>>,
) -> Select<'columns, T::Schema, Self> {
col.into_expr().into_select()
}
}
impl<S, T, From: EqTyp> FromExpr<S, Option<From>> for Option<T>
where
T: FromExpr<S, From>,
{
fn from_expr<'columns>(
col: impl IntoExpr<'columns, S, Typ = Option<From>>,
) -> Select<'columns, S, Self> {
let col = col.into_expr();
optional(|row| {
let col = row.and(col);
row.then_select(T::from_expr(col))
})
}
}
impl<S, From> FromExpr<S, From> for () {
fn from_expr<'columns>(
_col: impl IntoExpr<'columns, S, Typ = From>,
) -> Select<'columns, S, Self> {
().into_select()
}
}