rust_query/value/
trivial.rs

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