vantage_table/table/
base.rs1use std::marker::PhantomData;
2use std::sync::Arc;
3
4use indexmap::IndexMap;
5use vantage_expressions::Expression;
6use vantage_types::Entity;
7
8use crate::{
9 pagination::Pagination, references::Reference, sorting::SortDirection,
10 traits::table_source::TableSource,
11};
12
13pub type ExpressionFn<T, E> =
15 Arc<dyn Fn(&Table<T, E>) -> Expression<<T as TableSource>::Value> + Send + Sync>;
16
17#[derive(Clone)]
18pub struct Table<T, E>
19where
20 T: TableSource,
21 E: Entity<T::Value>,
22{
23 pub(super) data_source: T,
24 pub(super) _phantom: PhantomData<E>,
25 pub(super) table_name: String,
26 pub(super) columns: IndexMap<String, T::Column<T::AnyType>>,
27 pub(super) conditions: IndexMap<i64, T::Condition>,
28 pub(super) next_condition_id: i64,
29 pub(super) order_by: IndexMap<i64, (T::Condition, SortDirection)>,
30 pub(super) next_order_id: i64,
31 pub(super) refs: Option<IndexMap<String, Arc<dyn Reference>>>,
32 pub(super) expressions: IndexMap<String, ExpressionFn<T, E>>,
33 pub(super) pagination: Option<Pagination>,
34 pub(super) title_field: Option<String>,
35 pub(super) id_field: Option<String>,
36}
37
38impl<T: TableSource, E: Entity<T::Value>> Table<T, E> {
39 pub fn new(table_name: impl Into<String>, data_source: T) -> Self {
41 Self {
42 data_source,
43 _phantom: PhantomData,
44 table_name: table_name.into(),
45 columns: IndexMap::new(),
46 conditions: IndexMap::new(),
47 next_condition_id: 1,
48 order_by: IndexMap::new(),
49 next_order_id: 1,
50 refs: None,
51 expressions: IndexMap::new(),
52 pagination: None,
53 title_field: None,
54 id_field: None,
55 }
56 }
57
58 pub fn into_entity<E2: Entity<T::Value>>(self) -> Table<T, E2> {
60 Table {
61 data_source: self.data_source,
62 _phantom: PhantomData,
63 table_name: self.table_name,
64 columns: self.columns,
65 conditions: self.conditions,
66 next_condition_id: self.next_condition_id,
67 order_by: self.order_by,
68 next_order_id: self.next_order_id,
69 refs: self.refs,
70 expressions: IndexMap::new(),
71 pagination: self.pagination,
72 title_field: self.title_field,
73 id_field: self.id_field,
74 }
75 }
76
77 pub fn with<F>(mut self, func: F) -> Self
79 where
80 F: FnOnce(&mut Self),
81 {
82 func(&mut self);
83 self
84 }
85
86 pub fn table_name(&self) -> &str {
88 &self.table_name
89 }
90
91 pub fn data_source(&self) -> &T {
93 &self.data_source
94 }
95
96 pub(crate) fn conditions_mut(&mut self) -> &mut IndexMap<i64, T::Condition> {
98 &mut self.conditions
99 }
100
101 pub(crate) fn next_condition_id_mut(&mut self) -> &mut i64 {
103 &mut self.next_condition_id
104 }
105
106 pub fn title_field(&self) -> Option<&T::Column<T::AnyType>> {
108 self.title_field
109 .as_ref()
110 .and_then(|name| self.columns.get(name))
111 }
112
113 pub fn id_field(&self) -> Option<&T::Column<T::AnyType>> {
115 self.id_field
116 .as_ref()
117 .and_then(|name| self.columns.get(name))
118 }
119
120 pub fn pagination(&self) -> Option<&Pagination> {
122 self.pagination.as_ref()
123 }
124}
125
126impl<T: TableSource, E: Entity<T::Value>> std::ops::Index<&str> for Table<T, E> {
127 type Output = T::Column<T::AnyType>;
128
129 fn index(&self, index: &str) -> &Self::Output {
130 &self.columns[index]
131 }
132}
133
134impl<T: TableSource, E: Entity<T::Value>> std::fmt::Debug for Table<T, E> {
135 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136 f.debug_struct("Table")
137 .field("table_name", &self.table_name)
138 .field("columns", &self.columns.keys().collect::<Vec<_>>())
139 .field("conditions_count", &self.conditions.len())
140 .field(
141 "refs_count",
142 &self.refs.as_ref().map(|r| r.len()).unwrap_or(0),
143 )
144 .field("expressions_count", &self.expressions.len())
145 .finish()
146 }
147}