tablo_core/column/
computed.rs1use std::sync::Arc;
4
5use derive_where::derive_where;
6use topcoat::context::Cx;
7
8use super::{Column, ColumnToggle, ColumnWidth, Includes};
9use crate::display::Alignment;
10
11#[derive_where(Clone, Debug)]
28pub struct ComputedColumn<M> {
29 name: String,
30 label: crate::Text,
31 #[derive_where(skip(Debug))]
32 project: Arc<dyn Fn(&M) -> String + Send + Sync>,
33 width: ColumnWidth,
34 alignment: Alignment,
35 toggle: ColumnToggle,
36 includes: Includes<M>,
38 reads: Option<crate::lens::Reads<M>>,
40}
41
42impl<M> ComputedColumn<M>
43where
44 M: toasty::schema::Model,
45{
46 pub fn new(
49 label: impl Into<crate::Text>,
50 project: impl Fn(&M) -> String + Send + Sync + 'static,
51 ) -> Self {
52 let label = label.into();
53 Self {
54 name: label.key(),
55 label,
56 project: Arc::new(project),
57 width: ColumnWidth::Auto,
58 alignment: Alignment::Start,
59 toggle: ColumnToggle::Fixed,
60 includes: Includes::new(),
61 reads: None,
62 }
63 }
64
65 pub fn include_unscoped<T>(mut self, relation: impl Into<toasty::stmt::Include<M, T>>) -> Self {
70 self.includes = self.includes.with(relation);
71 self
72 }
73
74 pub fn reading(mut self, reads: crate::lens::Reads<M>) -> Self {
78 self.reads = Some(reads);
79 self
80 }
81
82 pub fn width(mut self, width: ColumnWidth) -> Self {
84 self.width = width;
85 self
86 }
87
88 pub fn align(mut self, alignment: Alignment) -> Self {
90 self.alignment = alignment;
91 self
92 }
93
94 toggle_builders!(toggle);
95}
96
97impl<M> Column<M> for ComputedColumn<M>
98where
99 M: toasty::schema::Model + Send + Sync + 'static,
100{
101 fn name(&self) -> &str {
102 &self.name
103 }
104
105 fn label(&self) -> crate::Text {
106 self.label.clone()
107 }
108
109 fn text(&self, _cx: &Cx, row: &M) -> String {
110 (self.project)(row)
111 }
112
113 fn column_width(&self) -> ColumnWidth {
114 self.width
115 }
116
117 fn toggle(&self) -> ColumnToggle {
118 self.toggle
119 }
120
121 fn alignment(&self) -> Alignment {
122 self.alignment
123 }
124
125 fn includes(&self) -> Includes<M> {
126 self.includes.clone()
127 }
128
129 fn reads(&self) -> Option<crate::lens::Reads<M>> {
130 self.reads.clone()
131 }
132}