Skip to main content

tablo_core/column/relation/
shared.rs

1//! The builders, the [`Column`] impl and the sealed internals both relation columns share.
2
3use super::*;
4
5/// The builders and the [`Column`] impl both relation columns share.
6macro_rules! relation_column {
7    ($ty:ident) => {
8        impl<M> $ty<M> {
9            /// Replace the label the field's name gives it, and name the column after the label,
10            /// as a [`ComputedColumn`](crate::ComputedColumn) is: two columns over one relation
11            /// need two labels.
12            pub fn label(mut self, label: impl Into<crate::Text>) -> Self {
13                self.relation.relabel(label.into());
14                self
15            }
16
17            /// Declare this column's width.
18            pub fn width(mut self, width: ColumnWidth) -> Self {
19                self.relation.width = width;
20                self
21            }
22
23            toggle_builders!(relation.toggle);
24        }
25
26        impl<M> Column<M> for $ty<M>
27        where
28            M: toasty::schema::Model + Send + Sync + 'static,
29        {
30            fn name(&self) -> &str {
31                &self.relation.name
32            }
33
34            fn label(&self) -> crate::Text {
35                self.relation.label()
36            }
37
38            fn text(&self, cx: &Cx, row: &M) -> String {
39                self.relation.text(self.loaded_text(cx, row))
40            }
41
42            fn column_width(&self) -> ColumnWidth {
43                self.relation.width
44            }
45
46            fn toggle(&self) -> ColumnToggle {
47                self.relation.toggle
48            }
49
50            fn includes(&self) -> Includes<M> {
51                self.relation.includes.clone()
52            }
53
54            fn reads(&self) -> Option<crate::lens::Reads<M>> {
55                Some(self.relation.reads.clone())
56            }
57
58            fn internals(&self) -> &dyn crate::column::ColumnInternals<M> {
59                self
60            }
61        }
62
63        impl<M> crate::column::ColumnInternals<M> for $ty<M>
64        where
65            M: toasty::schema::Model + Send + Sync + 'static,
66        {
67            fn restrict<'a>(
68                &'a self,
69                cx: &'a Cx,
70                rows: &'a [M],
71                ex: &'a mut dyn Executor,
72            ) -> BoxFuture<'a, Result<()>> {
73                match &self.relation.restrict {
74                    Some(restrict) => restrict(cx, rows, ex),
75                    None => Box::pin(async { Ok(()) }),
76                }
77            }
78
79            fn masked(&self, cx: &Cx) -> bool {
80                self.relation
81                    .masked
82                    .as_ref()
83                    .is_some_and(|masked| masked(cx))
84            }
85
86            fn related(&self) -> Related {
87                self.relation.related
88            }
89
90            fn misdeclared(&self) -> Option<DeclarationErrorKind> {
91                self.relation.misdeclared.clone()
92            }
93
94            fn unavailable_source(&self, cx: &Cx) -> Option<&'static str> {
95                self.relation
96                    .source
97                    .filter(|(_, available)| !available(cx))
98                    .map(|(source, _)| source)
99            }
100        }
101    };
102}
103
104relation_column!(RelationColumn);
105relation_column!(CountColumn);