Skip to main content

rust_query/value/
from_expr.rs

1use crate::{IntoExpr, IntoSelect, Table, TableRow, optional, select::Select, value::EqTyp};
2
3/// Trait for values that can be retrieved from the database using one expression.
4///
5/// This is most likely the trait that you want to implement for your custom datatype.
6/// Together with the [crate::IntoExpr] trait.
7///
8/// Note that this trait can also be implemented using the [derive@rust_query::FromExpr] derive macro.
9pub trait FromExpr<S, From>: 'static + Sized {
10    /// How to turn the expression into a [Select].
11    fn from_expr<'columns>(
12        col: impl IntoExpr<'columns, S, Typ = From>,
13    ) -> Select<'columns, S, Self>;
14}
15
16macro_rules! from_expr {
17    ($typ:ty) => {
18        impl<S> FromExpr<S, $typ> for $typ {
19            fn from_expr<'columns>(
20                col: impl IntoExpr<'columns, S, Typ = $typ>,
21            ) -> Select<'columns, S, Self> {
22                col.into_expr().into_select()
23            }
24        }
25    };
26}
27
28from_expr! {String}
29from_expr! {Vec<u8>}
30from_expr! {i64}
31from_expr! {f64}
32from_expr! {bool}
33
34impl<T: Table> FromExpr<T::Schema, TableRow<T>> for TableRow<T> {
35    fn from_expr<'columns>(
36        col: impl IntoExpr<'columns, T::Schema, Typ = TableRow<T>>,
37    ) -> Select<'columns, T::Schema, Self> {
38        col.into_expr().into_select()
39    }
40}
41
42impl<S, T, From: EqTyp> FromExpr<S, Option<From>> for Option<T>
43where
44    T: FromExpr<S, From>,
45{
46    fn from_expr<'columns>(
47        col: impl IntoExpr<'columns, S, Typ = Option<From>>,
48    ) -> Select<'columns, S, Self> {
49        let col = col.into_expr();
50        optional(|row| {
51            let col = row.and(col);
52            row.then_select(T::from_expr(col))
53        })
54    }
55}
56
57impl<S, From> FromExpr<S, From> for () {
58    fn from_expr<'columns>(
59        _col: impl IntoExpr<'columns, S, Typ = From>,
60    ) -> Select<'columns, S, Self> {
61        ().into_select()
62    }
63}