1use std::marker::PhantomData;
2
3use ref_cast::{RefCastCustom, ref_cast_custom};
4
5use crate::{
6 Expr, IntoExpr, Table,
7 alias::Field,
8 ast::MySelect,
9 value::{DynTypedExpr, NumTyp},
10};
11
12pub struct Update<'t, S, Typ> {
14 inner: Box<dyn 't + Fn(Expr<'t, S, Typ>) -> Expr<'t, S, Typ>>,
15}
16
17impl<'t, S, Typ> Default for Update<'t, S, Typ> {
18 fn default() -> Self {
19 Self {
20 inner: Box::new(|x| x),
21 }
22 }
23}
24
25impl<'t, S: 't, Typ: 't> Update<'t, S, Typ> {
26 pub fn set(val: impl IntoExpr<'t, S, Typ = Typ>) -> Self {
28 let val = val.into_expr();
29 Self {
30 inner: Box::new(move |_| val.clone()),
31 }
32 }
33
34 #[doc(hidden)]
35 pub fn apply(&self, val: impl IntoExpr<'t, S, Typ = Typ>) -> Expr<'t, S, Typ> {
36 (self.inner)(val.into_expr())
37 }
38}
39
40impl<'t, S: 't, Typ: NumTyp> Update<'t, S, Typ> {
41 pub fn add(val: impl IntoExpr<'t, S, Typ = Typ>) -> Self {
43 let val = val.into_expr();
44 Self {
45 inner: Box::new(move |old| old.add(&val)),
46 }
47 }
48}
49
50pub trait TableInsert<'t> {
52 type T: Table;
53 fn into_insert(self) -> <Self::T as Table>::Insert<'t>;
54}
55
56#[derive(RefCastCustom)]
57#[repr(transparent)]
58pub struct Reader<'t, S> {
59 pub(crate) ast: MySelect,
60 pub(crate) _p: PhantomData<S>,
61 pub(crate) _p2: PhantomData<fn(&'t ()) -> &'t ()>,
62}
63
64impl<'t, S> Reader<'t, S> {
65 #[ref_cast_custom]
66 pub(crate) fn new(select: &MySelect) -> &Self;
67}
68
69impl<'t, S> Reader<'t, S> {
70 pub fn col(&self, name: &'static str, val: impl IntoExpr<'t, S>) {
71 self.col_erased(name, val.into_expr().inner.erase());
72 }
73
74 pub(crate) fn col_erased(&self, name: &'static str, val: DynTypedExpr) {
75 let field = Field::Str(name);
76 let expr = (val.0)(self.ast.builder());
77 self.ast.select.push(Box::new((expr, field)))
78 }
79}