Skip to main content

keelson_models/
table.rs

1use std::fmt;
2use std::marker::PhantomData;
3
4use keelson_core::Mod;
5
6use crate::mutate::{ModelDelete, ModelInsert, ModelUpdate};
7use crate::select::ModelSelect;
8use crate::{Table, View};
9
10/// The model's entry point — what `users::table()` (or, for a `SELECT`-only
11/// model, `reports::view()`) returns.
12///
13/// One zero-sized type for both: the query side needs only [`View`], and the
14/// mutations are bounded on [`Table`], so on a view model
15/// `insert`/`update`/`delete` simply do not exist — the `View`/`Table` split
16/// enforced where it is felt, at the call site.
17pub struct ModelTable<M> {
18    _model: PhantomData<M>,
19}
20
21impl<M> fmt::Debug for ModelTable<M> {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        f.write_str("ModelTable")
24    }
25}
26
27impl<M> Clone for ModelTable<M> {
28    fn clone(&self) -> Self {
29        *self
30    }
31}
32
33impl<M> Copy for ModelTable<M> {}
34
35impl<M> Default for ModelTable<M> {
36    fn default() -> Self {
37        ModelTable::new()
38    }
39}
40
41impl<M> ModelTable<M> {
42    /// The entry point value. Generated `table()`/`view()` functions return
43    /// this.
44    pub const fn new() -> Self {
45        ModelTable {
46            _model: PhantomData,
47        }
48    }
49}
50
51impl<M: View> ModelTable<M> {
52    /// A `SELECT` over this model: the base select plus `mods` — typed
53    /// filters, Layer 1 mods, preloads and then-loads, all in one tuple.
54    ///
55    /// ```ignore
56    /// let adults = users::table().query((
57    ///     users::age().gte(21),   // typed: a &str here is a compile error
58    ///     select::limit(20),      // Layer 1 mods mix in directly
59    /// )).all(&db).await?;
60    /// ```
61    pub fn query(self, mods: impl Mod<ModelSelect<M>>) -> ModelSelect<M> {
62        let mut q = ModelSelect::new(M::base_select());
63        mods.apply(&mut q);
64        q
65    }
66}
67
68impl<M: Table> ModelTable<M> {
69    /// An `INSERT` of the setter's set fields.
70    ///
71    /// ```ignore
72    /// let u = users::table().insert(users::Setter {
73    ///     name: set("Stephen"),
74    ///     ..Default::default()
75    /// }).one(&db).await?;
76    /// ```
77    pub fn insert(self, setter: M::Setter) -> ModelInsert<M> {
78        ModelInsert::new(setter)
79    }
80
81    /// An `UPDATE` of the setter's set fields, filtered and modified by
82    /// `mods` (an unfiltered update really is the whole table, exactly as in
83    /// SQL).
84    pub fn update(self, setter: M::Setter, mods: impl Mod<ModelUpdate<M>>) -> ModelUpdate<M> {
85        ModelUpdate::new(setter, mods)
86    }
87
88    /// A `DELETE`, filtered and modified by `mods`.
89    pub fn delete(self, mods: impl Mod<ModelDelete<M>>) -> ModelDelete<M> {
90        ModelDelete::new(mods)
91    }
92}