vantage_table/table/impls/
conditions.rs1use vantage_core::{Result, error};
2use vantage_types::Entity;
3
4use crate::{conditions::ConditionHandle, table::Table, traits::table_source::TableSource};
5
6impl<T: TableSource, E: Entity<T::Value>> Table<T, E> {
7 pub fn add_condition(&mut self, condition: impl Into<T::Condition>) {
10 let condition = condition.into();
11 if let Some((column, value)) = self.data_source.condition_equality(&condition) {
12 self.add_invariant(column, value);
13 }
14 let id = -self.next_condition_id;
15 self.next_condition_id += 1;
16 self.conditions.insert(id, condition);
17 }
18
19 pub fn temp_add_condition(&mut self, condition: impl Into<T::Condition>) -> ConditionHandle {
21 let id = self.next_condition_id;
22 self.next_condition_id += 1;
23 self.conditions.insert(id, condition.into());
24 ConditionHandle::new(id)
25 }
26
27 pub fn temp_remove_condition(&mut self, handle: ConditionHandle) -> Result<()> {
29 if handle.0 <= 0 {
30 return Err(error!("Cannot remove permanent condition"));
31 }
32 self.conditions.shift_remove(&handle.0);
33 Ok(())
34 }
35
36 pub fn conditions(&self) -> impl Iterator<Item = &T::Condition> {
38 self.conditions.values()
39 }
40
41 pub fn with_condition(mut self, condition: impl Into<T::Condition>) -> Self {
43 self.add_condition(condition);
44 self
45 }
46
47 pub fn add_search(&mut self, value: &str)
49 where
50 T: Sized,
51 {
52 let condition = self.data_source().search_table_condition(self, value);
53 self.add_condition(condition);
54 }
55
56 pub fn with_search(mut self, value: &str) -> Self
58 where
59 T: Sized,
60 {
61 self.add_search(value);
62 self
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use crate::mocks::mock_table_source::MockTableSource;
69
70 use super::*;
71 use vantage_expressions::expr_any;
72 use vantage_types::EmptyEntity;
73
74 #[test]
75 fn test_temp_conditions() {
76 let ds = MockTableSource::new();
77 let mut table = Table::<_, EmptyEntity>::new("test", ds);
78
79 table.add_condition(expr_any!("perm1"));
81 assert_eq!(table.conditions().count(), 1);
82
83 let handle1 = table.temp_add_condition(expr_any!("temp1"));
85 let handle2 = table.temp_add_condition(expr_any!("temp2"));
86 assert_eq!(table.conditions().count(), 3);
87
88 table.temp_remove_condition(handle1).unwrap();
90 assert_eq!(table.conditions().count(), 2);
91
92 table.add_condition(expr_any!("perm2"));
94 assert_eq!(table.conditions().count(), 3);
95
96 table.temp_remove_condition(handle2).unwrap();
98 assert_eq!(table.conditions().count(), 2);
99
100 assert_eq!(table.conditions().count(), 2);
102 }
103
104 #[test]
105 fn literal_equality_condition_registers_an_invariant() {
106 use serde_json::json;
107 use vantage_expressions::{Expression, ExpressiveEnum};
108 let mut table = Table::<_, EmptyEntity>::new("t", MockTableSource::new());
109 table.add_condition(Expression::new(
110 "{} = {}",
111 vec![
112 ExpressiveEnum::Nested(Expression::new("parent", vec![])),
113 ExpressiveEnum::Nested(Expression::new(
114 "{}",
115 vec![ExpressiveEnum::Scalar(json!("p1"))],
116 )),
117 ],
118 ));
119 assert_eq!(table.invariants().get("parent"), Some(&json!("p1")));
120 let pattern = "%x%".to_string();
121 let _ = table.temp_add_condition(expr_any!("name LIKE {}", pattern));
122 assert_eq!(
123 table.invariants().len(),
124 1,
125 "temp conditions register nothing"
126 );
127 }
128
129 #[test]
130 fn test_cannot_remove_permanent_condition() {
131 let ds = MockTableSource::new();
132 let mut table = Table::<_, EmptyEntity>::new("test", ds);
133
134 table.add_condition(expr_any!("perm"));
135 let _handle = table.temp_add_condition(expr_any!("temp"));
136
137 let fake_handle = ConditionHandle::new(-1);
139 let result = table.temp_remove_condition(fake_handle);
140 assert!(result.is_err());
141 }
142}