1use super::*;
2use crate::element::*;
3use crate::error::{Error, Result};
4use crate::Timestamp;
5use serde::{Deserialize, Serialize};
6use std::default::Default;
7
8#[inline]
9fn is_false(v: &bool) -> bool {
10 !v
11}
12
13const MIN_TIME: Timestamp = Timestamp::min_value();
14const MAX_TIME: Timestamp = Timestamp::max_value();
15
16#[inline]
17fn time_is_min(v: &Timestamp) -> bool {
18 *v == MIN_TIME
19}
20
21#[inline]
22fn time_is_max(v: &Timestamp) -> bool {
23 *v == MAX_TIME
24}
25
26#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
51#[serde(deny_unknown_fields, default)]
52pub struct TimeValidator {
53 #[serde(skip_serializing_if = "String::is_empty")]
55 pub comment: String,
56 #[serde(skip_serializing_if = "time_is_max")]
58 pub max: Timestamp,
59 #[serde(skip_serializing_if = "time_is_min")]
61 pub min: Timestamp,
62 #[serde(skip_serializing_if = "is_false")]
64 pub ex_max: bool,
65 #[serde(skip_serializing_if = "is_false")]
67 pub ex_min: bool,
68 #[serde(rename = "in", skip_serializing_if = "Vec::is_empty")]
70 pub in_list: Vec<Timestamp>,
71 #[serde(rename = "nin", skip_serializing_if = "Vec::is_empty")]
73 pub nin_list: Vec<Timestamp>,
74 #[serde(skip_serializing_if = "is_false")]
76 pub query: bool,
77 #[serde(skip_serializing_if = "is_false")]
80 pub ord: bool,
81}
82
83impl Default for TimeValidator {
84 fn default() -> Self {
85 Self {
86 comment: String::new(),
87 max: MAX_TIME,
88 min: MIN_TIME,
89 ex_max: false,
90 ex_min: false,
91 in_list: Vec::new(),
92 nin_list: Vec::new(),
93 query: false,
94 ord: false,
95 }
96 }
97}
98
99impl TimeValidator {
100 pub fn new() -> Self {
102 Self::default()
103 }
104
105 pub fn comment(mut self, comment: impl Into<String>) -> Self {
107 self.comment = comment.into();
108 self
109 }
110
111 pub fn max(mut self, max: impl Into<Timestamp>) -> Self {
113 self.max = max.into();
114 self
115 }
116
117 pub fn min(mut self, min: impl Into<Timestamp>) -> Self {
119 self.min = min.into();
120 self
121 }
122
123 pub fn ex_max(mut self, ex_max: bool) -> Self {
125 self.ex_max = ex_max;
126 self
127 }
128
129 pub fn ex_min(mut self, ex_min: bool) -> Self {
131 self.ex_min = ex_min;
132 self
133 }
134
135 pub fn in_add(mut self, add: impl Into<Timestamp>) -> Self {
137 self.in_list.push(add.into());
138 self
139 }
140
141 pub fn nin_add(mut self, add: impl Into<Timestamp>) -> Self {
143 self.nin_list.push(add.into());
144 self
145 }
146
147 pub fn query(mut self, query: bool) -> Self {
149 self.query = query;
150 self
151 }
152
153 pub fn ord(mut self, ord: bool) -> Self {
155 self.ord = ord;
156 self
157 }
158
159 pub fn build(self) -> Validator {
161 Validator::Time(Box::new(self))
162 }
163
164 pub(crate) fn validate(&self, parser: &mut Parser) -> Result<()> {
165 let elem = parser
166 .next()
167 .ok_or_else(|| Error::FailValidate("Expected a timestamp".to_string()))??;
168 let val = if let Element::Timestamp(v) = elem {
169 v
170 } else {
171 return Err(Error::FailValidate(format!(
172 "Expected Time, got {}",
173 elem.name()
174 )));
175 };
176
177 let max_pass = if self.ex_max {
179 val < self.max
180 } else {
181 val <= self.max
182 };
183 let min_pass = if self.ex_min {
184 val > self.min
185 } else {
186 val >= self.min
187 };
188 if !max_pass {
189 return Err(Error::FailValidate(
190 "Timestamp greater than maximum allowed".to_string(),
191 ));
192 }
193 if !min_pass {
194 return Err(Error::FailValidate(
195 "Timestamp less than minimum allowed".to_string(),
196 ));
197 }
198
199 if !self.in_list.is_empty() && !self.in_list.iter().any(|v| *v == val) {
201 return Err(Error::FailValidate(
202 "Timestamp is not on `in` list".to_string(),
203 ));
204 }
205 if self.nin_list.iter().any(|v| *v == val) {
206 return Err(Error::FailValidate(
207 "Timestamp is on `nin` list".to_string(),
208 ));
209 }
210
211 Ok(())
212 }
213
214 fn query_check_self(&self, other: &Self) -> bool {
215 (self.query || (other.in_list.is_empty() && other.nin_list.is_empty()))
216 && (self.ord
217 || (!other.ex_min
218 && !other.ex_max
219 && time_is_min(&other.min)
220 && time_is_max(&other.max)))
221 }
222
223 pub(crate) fn query_check(&self, other: &Validator) -> bool {
224 match other {
225 Validator::Time(other) => self.query_check_self(other),
226 Validator::Multi(list) => list.iter().all(|other| match other {
227 Validator::Time(other) => self.query_check_self(other),
228 _ => false,
229 }),
230 Validator::Any => true,
231 _ => false,
232 }
233 }
234}
235
236#[cfg(test)]
237mod test {
238 use super::*;
239 use crate::{de::FogDeserializer, ser::FogSerializer};
240
241 #[test]
242 fn default_ser() {
243 let schema = TimeValidator::default();
245 let mut ser = FogSerializer::default();
246 schema.serialize(&mut ser).unwrap();
247 let expected: Vec<u8> = vec![0x80];
248 let actual = ser.finish();
249 println!("expected: {:x?}", expected);
250 println!("actual: {:x?}", actual);
251 assert_eq!(expected, actual);
252
253 let mut de = FogDeserializer::new(&actual);
254 let decoded = TimeValidator::deserialize(&mut de).unwrap();
255 assert_eq!(schema, decoded);
256 }
257
258 #[test]
259 fn example_ser() {
260 let schema = TimeValidator {
261 comment: "The year 2020".to_string(),
262 min: Timestamp::from_utc(1577854800, 0).unwrap(),
263 max: Timestamp::from_utc(1609477200, 0).unwrap(),
264 ex_min: false,
265 ex_max: true,
266 in_list: Vec::new(),
267 nin_list: Vec::new(),
268 query: true,
269 ord: true,
270 };
271 let mut ser = FogSerializer::default();
272 schema.serialize(&mut ser).unwrap();
273 let mut expected: Vec<u8> = vec![0x86];
274 serialize_elem(&mut expected, Element::Str("comment"));
275 serialize_elem(&mut expected, Element::Str("The year 2020"));
276 serialize_elem(&mut expected, Element::Str("ex_max"));
277 serialize_elem(&mut expected, Element::Bool(true));
278 serialize_elem(&mut expected, Element::Str("max"));
279 serialize_elem(
280 &mut expected,
281 Element::Timestamp(Timestamp::from_utc(1609477200, 0).unwrap()),
282 );
283 serialize_elem(&mut expected, Element::Str("min"));
284 serialize_elem(
285 &mut expected,
286 Element::Timestamp(Timestamp::from_utc(1577854800, 0).unwrap()),
287 );
288 serialize_elem(&mut expected, Element::Str("ord"));
289 serialize_elem(&mut expected, Element::Bool(true));
290 serialize_elem(&mut expected, Element::Str("query"));
291 serialize_elem(&mut expected, Element::Bool(true));
292 let actual = ser.finish();
293 println!("expected: {:x?}", expected);
294 println!("actual: {:x?}", actual);
295 assert_eq!(expected, actual);
296
297 let mut de = FogDeserializer::with_debug(&actual, " ".to_string());
298 match TimeValidator::deserialize(&mut de) {
299 Ok(decoded) => assert_eq!(schema, decoded),
300 Err(e) => {
301 println!("{}", de.get_debug().unwrap());
302 println!("Error: {}", e);
303 panic!("Couldn't decode");
304 }
305 }
306 }
307}