fog_pack/validator/
integer.rs1use super::*;
2use crate::element::*;
3use crate::error::{Error, Result};
4use crate::*;
5use serde::{Deserialize, Serialize};
6
7#[inline]
8fn is_false(v: &bool) -> bool {
9 !v
10}
11
12#[inline]
13fn u64_is_zero(v: &u64) -> bool {
14 *v == 0
15}
16
17#[inline]
18fn int_is_max(v: &Integer) -> bool {
19 v.as_u64().map(|v| v == u64::MAX).unwrap_or(false)
20}
21
22#[inline]
23fn int_is_min(v: &Integer) -> bool {
24 v.as_i64().map(|v| v == i64::MIN).unwrap_or(false)
25}
26
27#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
57#[serde(deny_unknown_fields, default)]
58pub struct IntValidator {
59 #[serde(skip_serializing_if = "String::is_empty")]
61 pub comment: String,
62 #[serde(skip_serializing_if = "u64_is_zero")]
65 pub bits_clr: u64,
66 #[serde(skip_serializing_if = "u64_is_zero")]
69 pub bits_set: u64,
70 #[serde(skip_serializing_if = "int_is_max")]
72 pub max: Integer,
73 #[serde(skip_serializing_if = "int_is_min")]
75 pub min: Integer,
76 #[serde(skip_serializing_if = "is_false")]
78 pub ex_max: bool,
79 #[serde(skip_serializing_if = "is_false")]
81 pub ex_min: bool,
82 #[serde(rename = "in", skip_serializing_if = "Vec::is_empty")]
84 pub in_list: Vec<Integer>,
85 #[serde(rename = "nin", skip_serializing_if = "Vec::is_empty")]
87 pub nin_list: Vec<Integer>,
88 #[serde(skip_serializing_if = "is_false")]
90 pub query: bool,
91 #[serde(skip_serializing_if = "is_false")]
94 pub bit: bool,
95 #[serde(skip_serializing_if = "is_false")]
98 pub ord: bool,
99}
100
101impl std::default::Default for IntValidator {
102 fn default() -> Self {
103 Self {
104 comment: String::new(),
105 bits_clr: 0,
106 bits_set: 0,
107 max: Integer::max_value(),
108 min: Integer::min_value(),
109 ex_max: false,
110 ex_min: false,
111 in_list: Vec::new(),
112 nin_list: Vec::new(),
113 query: false,
114 bit: false,
115 ord: false,
116 }
117 }
118}
119
120impl IntValidator {
121 pub fn new() -> Self {
123 Self::default()
124 }
125
126 pub fn comment(mut self, comment: impl Into<String>) -> Self {
128 self.comment = comment.into();
129 self
130 }
131
132 pub fn bits_set(mut self, bits_set: u64) -> Self {
134 self.bits_set = bits_set;
135 self
136 }
137
138 pub fn bits_clr(mut self, bits_clr: u64) -> Self {
140 self.bits_clr = bits_clr;
141 self
142 }
143
144 pub fn max(mut self, max: impl Into<Integer>) -> Self {
146 self.max = max.into();
147 self
148 }
149
150 pub fn min(mut self, min: impl Into<Integer>) -> Self {
152 self.min = min.into();
153 self
154 }
155
156 pub fn ex_max(mut self, ex_max: bool) -> Self {
158 self.ex_max = ex_max;
159 self
160 }
161
162 pub fn ex_min(mut self, ex_min: bool) -> Self {
164 self.ex_min = ex_min;
165 self
166 }
167
168 pub fn in_add(mut self, add: impl Into<Integer>) -> Self {
170 self.in_list.push(add.into());
171 self
172 }
173
174 pub fn nin_add(mut self, add: impl Into<Integer>) -> Self {
176 self.nin_list.push(add.into());
177 self
178 }
179
180 pub fn query(mut self, query: bool) -> Self {
182 self.query = query;
183 self
184 }
185
186 pub fn bit(mut self, bit: bool) -> Self {
188 self.bit = bit;
189 self
190 }
191
192 pub fn ord(mut self, ord: bool) -> Self {
194 self.ord = ord;
195 self
196 }
197
198 pub fn build(self) -> Validator {
200 Validator::Int(Box::new(self))
201 }
202
203 pub(crate) fn validate(&self, parser: &mut Parser) -> Result<()> {
204 let elem = parser
205 .next()
206 .ok_or_else(|| Error::FailValidate("Expected a integer".to_string()))??;
207 let int = if let Element::Int(v) = elem {
208 v
209 } else {
210 return Err(Error::FailValidate(format!(
211 "Expected Int, got {}",
212 elem.name()
213 )));
214 };
215 let bits = int.as_bits();
216 if !self.in_list.is_empty() && !self.in_list.iter().any(|v| *v == int) {
217 return Err(Error::FailValidate(
218 "Integer is not on `in` list".to_string(),
219 ));
220 }
221 if self.nin_list.iter().any(|v| *v == int) {
222 return Err(Error::FailValidate("Integer is on `nin` list".to_string()));
223 }
224 if (bits & self.bits_clr) != 0 {
225 return Err(Error::FailValidate(
226 "Integer does not have all required bits cleared".to_string(),
227 ));
228 }
229 if (bits & self.bits_set) != self.bits_set {
230 return Err(Error::FailValidate(
231 "Integer does not have all required bits set".to_string(),
232 ));
233 }
234 match int.cmp(&self.max) {
235 std::cmp::Ordering::Equal if self.ex_max => {
236 return Err(Error::FailValidate(
237 "Integer greater than maximum allowed".to_string(),
238 ))
239 }
240 std::cmp::Ordering::Greater => {
241 return Err(Error::FailValidate(
242 "Integer greater than maximum allowed".to_string(),
243 ))
244 }
245 _ => (),
246 }
247 match int.cmp(&self.min) {
248 std::cmp::Ordering::Equal if self.ex_min => {
249 return Err(Error::FailValidate(
250 "Integer less than minimum allowed".to_string(),
251 ))
252 }
253 std::cmp::Ordering::Less => {
254 return Err(Error::FailValidate(
255 "Integer less than minimum allowed".to_string(),
256 ))
257 }
258 _ => (),
259 }
260 Ok(())
261 }
262
263 fn query_check_int(&self, other: &Self) -> bool {
264 (self.query || (other.in_list.is_empty() && other.nin_list.is_empty()))
265 && (self.bit || (other.bits_clr == 0 && other.bits_set == 0))
266 && (self.ord
267 || (!other.ex_min
268 && !other.ex_max
269 && int_is_max(&other.max)
270 && int_is_min(&other.min)))
271 }
272
273 pub(crate) fn query_check(&self, other: &Validator) -> bool {
274 match other {
275 Validator::Int(other) => self.query_check_int(other),
276 Validator::Multi(list) => list.iter().all(|other| match other {
277 Validator::Int(other) => self.query_check_int(other),
278 _ => false,
279 }),
280 Validator::Any => true,
281 _ => false,
282 }
283 }
284}