gitql_core/values/
time.rs1use std::any::Any;
2use std::cmp::Ordering;
3
4use gitql_ast::operator::GroupComparisonOperator;
5use gitql_ast::types::time::TimeType;
6use gitql_ast::types::DataType;
7
8use super::base::Value;
9use super::boolean::BoolValue;
10
11#[derive(Clone)]
12pub struct TimeValue {
13 pub value: String,
14}
15
16impl TimeValue {
17 pub fn new(time: String) -> Self {
18 TimeValue { value: time }
19 }
20}
21
22impl Value for TimeValue {
23 fn literal(&self) -> String {
24 self.value.to_string()
25 }
26
27 fn equals(&self, other: &Box<dyn Value>) -> bool {
28 if let Some(other_time) = other.as_any().downcast_ref::<TimeValue>() {
29 return self.value == other_time.value;
30 }
31 false
32 }
33
34 fn compare(&self, other: &Box<dyn Value>) -> Option<Ordering> {
35 if let Some(other_time) = other.as_any().downcast_ref::<TimeValue>() {
36 return self.value.partial_cmp(&other_time.value);
37 }
38 None
39 }
40
41 fn data_type(&self) -> Box<dyn DataType> {
42 Box::new(TimeType)
43 }
44
45 fn as_any(&self) -> &dyn Any {
46 self
47 }
48
49 fn eq_op(&self, other: &Box<dyn Value>) -> Result<Box<dyn Value>, String> {
50 if let Some(other_text) = other.as_any().downcast_ref::<TimeValue>() {
51 let are_equals = self.value == other_text.value;
52 return Ok(Box::new(BoolValue { value: are_equals }));
53 }
54 Err("Unexpected type to perform `=` with".to_string())
55 }
56
57 fn group_eq_op(
58 &self,
59 other: &Box<dyn Value>,
60 group_op: &GroupComparisonOperator,
61 ) -> Result<Box<dyn Value>, String> {
62 if other.is_array_of(|element_type| element_type.is_time()) {
63 let elements = &other.as_array().unwrap();
64 let mut matches_count = 0;
65 for element in elements.iter() {
66 if self.value == element.as_time().unwrap() {
67 matches_count += 1;
68 if GroupComparisonOperator::Any.eq(group_op) {
69 break;
70 }
71 }
72 }
73
74 let result = match group_op {
75 GroupComparisonOperator::All => matches_count == elements.len(),
76 GroupComparisonOperator::Any => matches_count > 0,
77 };
78
79 return Ok(Box::new(BoolValue::new(result)));
80 }
81 Err("Unexpected type to perform `=` with".to_string())
82 }
83
84 fn bang_eq_op(&self, other: &Box<dyn Value>) -> Result<Box<dyn Value>, String> {
85 if let Some(other_text) = other.as_any().downcast_ref::<TimeValue>() {
86 let are_equals = self.value != other_text.value;
87 return Ok(Box::new(BoolValue { value: are_equals }));
88 }
89 Err("Unexpected type to perform `!=` with".to_string())
90 }
91
92 fn group_bang_eq_op(
93 &self,
94 other: &Box<dyn Value>,
95 group_op: &GroupComparisonOperator,
96 ) -> Result<Box<dyn Value>, String> {
97 if other.is_array_of(|element_type| element_type.is_time()) {
98 let elements = &other.as_array().unwrap();
99 let mut matches_count = 0;
100 for element in elements.iter() {
101 if self.value != element.as_time().unwrap() {
102 matches_count += 1;
103 if GroupComparisonOperator::Any.eq(group_op) {
104 break;
105 }
106 }
107 }
108
109 let result = match group_op {
110 GroupComparisonOperator::All => matches_count == elements.len(),
111 GroupComparisonOperator::Any => matches_count > 0,
112 };
113
114 return Ok(Box::new(BoolValue::new(result)));
115 }
116 Err("Unexpected type to perform `!=` with".to_string())
117 }
118
119 fn gt_op(&self, other: &Box<dyn Value>) -> Result<Box<dyn Value>, String> {
120 if let Some(other_text) = other.as_any().downcast_ref::<TimeValue>() {
121 let are_equals = self.value > other_text.value;
122 return Ok(Box::new(BoolValue { value: are_equals }));
123 }
124 Err("Unexpected type to perform `>` with".to_string())
125 }
126
127 fn group_gt_op(
128 &self,
129 other: &Box<dyn Value>,
130 group_op: &GroupComparisonOperator,
131 ) -> Result<Box<dyn Value>, String> {
132 if other.is_array_of(|element_type| element_type.is_time()) {
133 let elements = &other.as_array().unwrap();
134 let mut matches_count = 0;
135 for element in elements.iter() {
136 if self.value > element.as_time().unwrap() {
137 matches_count += 1;
138 if GroupComparisonOperator::Any.eq(group_op) {
139 break;
140 }
141 }
142 }
143
144 let result = match group_op {
145 GroupComparisonOperator::All => matches_count == elements.len(),
146 GroupComparisonOperator::Any => matches_count > 0,
147 };
148
149 return Ok(Box::new(BoolValue::new(result)));
150 }
151 Err("Unexpected type to perform `>` with".to_string())
152 }
153
154 fn gte_op(&self, other: &Box<dyn Value>) -> Result<Box<dyn Value>, String> {
155 if let Some(other_text) = other.as_any().downcast_ref::<TimeValue>() {
156 let are_equals = self.value >= other_text.value;
157 return Ok(Box::new(BoolValue { value: are_equals }));
158 }
159 Err("Unexpected type to perform `>=` with".to_string())
160 }
161
162 fn group_gte_op(
163 &self,
164 other: &Box<dyn Value>,
165 group_op: &GroupComparisonOperator,
166 ) -> Result<Box<dyn Value>, String> {
167 if other.is_array_of(|element_type| element_type.is_time()) {
168 let elements = &other.as_array().unwrap();
169 let mut matches_count = 0;
170 for element in elements.iter() {
171 if self.value >= element.as_time().unwrap() {
172 matches_count += 1;
173 if GroupComparisonOperator::Any.eq(group_op) {
174 break;
175 }
176 }
177 }
178
179 let result = match group_op {
180 GroupComparisonOperator::All => matches_count == elements.len(),
181 GroupComparisonOperator::Any => matches_count > 0,
182 };
183
184 return Ok(Box::new(BoolValue::new(result)));
185 }
186 Err("Unexpected type to perform `>=` with".to_string())
187 }
188
189 fn lt_op(&self, other: &Box<dyn Value>) -> Result<Box<dyn Value>, String> {
190 if let Some(other_text) = other.as_any().downcast_ref::<TimeValue>() {
191 let are_equals = self.value < other_text.value;
192 return Ok(Box::new(BoolValue { value: are_equals }));
193 }
194 Err("Unexpected type to perform `<` with".to_string())
195 }
196
197 fn group_lt_op(
198 &self,
199 other: &Box<dyn Value>,
200 group_op: &GroupComparisonOperator,
201 ) -> Result<Box<dyn Value>, String> {
202 if other.is_array_of(|element_type| element_type.is_time()) {
203 let elements = &other.as_array().unwrap();
204 let mut matches_count = 0;
205 for element in elements.iter() {
206 if self.value < element.as_time().unwrap() {
207 matches_count += 1;
208 if GroupComparisonOperator::Any.eq(group_op) {
209 break;
210 }
211 }
212 }
213
214 let result = match group_op {
215 GroupComparisonOperator::All => matches_count == elements.len(),
216 GroupComparisonOperator::Any => matches_count > 0,
217 };
218
219 return Ok(Box::new(BoolValue::new(result)));
220 }
221 Err("Unexpected type to perform `<` with".to_string())
222 }
223
224 fn lte_op(&self, other: &Box<dyn Value>) -> Result<Box<dyn Value>, String> {
225 if let Some(other_text) = other.as_any().downcast_ref::<TimeValue>() {
226 let are_equals = self.value <= other_text.value;
227 return Ok(Box::new(BoolValue { value: are_equals }));
228 }
229 Err("Unexpected type to perform `<=` with".to_string())
230 }
231
232 fn group_lte_op(
233 &self,
234 other: &Box<dyn Value>,
235 group_op: &GroupComparisonOperator,
236 ) -> Result<Box<dyn Value>, String> {
237 if other.is_array_of(|element_type| element_type.is_time()) {
238 let elements = &other.as_array().unwrap();
239 let mut matches_count = 0;
240 for element in elements.iter() {
241 if self.value <= element.as_time().unwrap() {
242 matches_count += 1;
243 if GroupComparisonOperator::Any.eq(group_op) {
244 break;
245 }
246 }
247 }
248
249 let result = match group_op {
250 GroupComparisonOperator::All => matches_count == elements.len(),
251 GroupComparisonOperator::Any => matches_count > 0,
252 };
253
254 return Ok(Box::new(BoolValue::new(result)));
255 }
256 Err("Unexpected type to perform `<=` with".to_string())
257 }
258}