1use crate::path::config::cache::{RegexCache, RegexCacheInst};
2use regex::Regex;
3use serde_json::Value;
4
5pub fn size(left: Vec<&Value>, right: Vec<&Value>) -> bool {
9 if let Some(Value::Number(n)) = right.first() {
10 if let Some(sz) = n.as_f64() {
11 for el in left.iter() {
12 match el {
13 Value::String(v) if v.len() == sz as usize => true,
14 Value::Array(elems) if elems.len() == sz as usize => true,
15 Value::Object(fields) if fields.len() == sz as usize => true,
16 _ => return false,
17 };
18 }
19 return true;
20 }
21 }
22 false
23}
24
25pub fn sub_set_of(left: Vec<&Value>, right: Vec<&Value>) -> bool {
28 if left.is_empty() {
29 return true;
30 }
31 if right.is_empty() {
32 return false;
33 }
34
35 if let Some(elems) = left.first().and_then(|e| e.as_array()) {
36 if let Some(Value::Array(right_elems)) = right.first() {
37 if right_elems.is_empty() {
38 return false;
39 }
40
41 for el in elems {
42 let mut res = false;
43
44 for r in right_elems.iter() {
45 if el.eq(r) {
46 res = true
47 }
48 }
49 if !res {
50 return false;
51 }
52 }
53 return true;
54 }
55 }
56 false
57}
58
59pub fn any_of(left: Vec<&Value>, right: Vec<&Value>) -> bool {
62 if left.is_empty() {
63 return true;
64 }
65 if right.is_empty() {
66 return false;
67 }
68
69 if let Some(Value::Array(elems)) = right.first() {
70 if elems.is_empty() {
71 return false;
72 }
73
74 for el in left.iter() {
75 if let Some(left_elems) = el.as_array() {
76 for l in left_elems.iter() {
77 for r in elems.iter() {
78 if l.eq(r) {
79 return true;
80 }
81 }
82 }
83 } else {
84 for r in elems.iter() {
85 if el.eq(&r) {
86 return true;
87 }
88 }
89 }
90 }
91 }
92
93 false
94}
95
96pub fn regex(
98 left: Vec<&Value>,
99 right: Vec<&Value>,
100 cache: &RegexCache<impl RegexCacheInst + Clone>,
101) -> bool {
102 if left.is_empty() || right.is_empty() {
103 return false;
104 }
105
106 match right.first() {
107 Some(Value::String(str)) => {
108 if cache.is_implemented() {
109 cache
110 .get_instance()
111 .and_then(|inst| inst.validate(str, left))
112 .unwrap_or(false)
113 } else if let Ok(regex) = Regex::new(str) {
114 for el in left.iter() {
115 if let Some(v) = el.as_str() {
116 if regex.is_match(v) {
117 return true;
118 }
119 }
120 }
121 false
122 } else {
123 false
124 }
125 }
126 _ => false,
127 }
128}
129
130pub fn inside(left: Vec<&Value>, right: Vec<&Value>) -> bool {
132 if left.is_empty() {
133 return false;
134 }
135
136 match right.first() {
137 Some(Value::Array(elems)) => {
138 for el in left.iter() {
139 if elems.contains(el) {
140 return true;
141 }
142 }
143 false
144 }
145 Some(Value::Object(elems)) => {
146 for el in left.iter() {
147 for r in elems.values() {
148 if el.eq(&r) {
149 return true;
150 }
151 }
152 }
153 false
154 }
155 _ => false,
156 }
157}
158
159pub fn less(left: Vec<&Value>, right: Vec<&Value>) -> bool {
161 if left.len() == 1 && right.len() == 1 {
162 match (left.first(), right.first()) {
163 (Some(Value::Number(l)), Some(Value::Number(r))) => l
164 .as_f64()
165 .and_then(|v1| r.as_f64().map(|v2| v1 < v2))
166 .unwrap_or(false),
167 _ => false,
168 }
169 } else {
170 false
171 }
172}
173
174pub fn eq(left: Vec<&Value>, right: Vec<&Value>) -> bool {
176 if left.len() != right.len() {
177 false
178 } else {
179 left.iter().zip(right).map(|(a, b)| a.eq(&b)).all(|a| a)
180 }
181}
182
183#[cfg(test)]
184mod tests {
185 use crate::path::config::cache::RegexCache;
186 use crate::path::json::{any_of, eq, less, regex, size, sub_set_of};
187 use serde_json::{json, Value};
188
189 #[test]
190 fn value_eq_test() {
191 let left = json!({"value":42});
192 let right = json!({"value":42});
193 let right_uneq = json!([42]);
194
195 assert!(&left.eq(&right));
196 assert!(!&left.eq(&right_uneq));
197 }
198
199 #[test]
200 fn vec_value_test() {
201 let left = json!({"value":42});
202 let left1 = json!(42);
203 let left2 = json!([1, 2, 3]);
204 let left3 = json!({"value2":[42],"value":[42]});
205
206 let right = json!({"value":42});
207 let right1 = json!(42);
208 let right2 = json!([1, 2, 3]);
209 let right3 = json!({"value":[42],"value2":[42]});
210
211 assert!(eq(vec![&left], vec![&right]));
212
213 assert!(!eq(vec![], vec![&right]));
214 assert!(!eq(vec![&right], vec![]));
215
216 assert!(eq(
217 vec![&left, &left1, &left2, &left3],
218 vec![&right, &right1, &right2, &right3],
219 ));
220
221 assert!(!eq(
222 vec![&left1, &left, &left2, &left3],
223 vec![&right, &right1, &right2, &right3],
224 ));
225 }
226
227 #[test]
228 fn less_value_test() {
229 let left = json!(10);
230 let right = json!(11);
231
232 assert!(less(vec![&left], vec![&right]));
233 assert!(!less(vec![&right], vec![&left]));
234
235 let left = json!(-10);
236 let right = json!(-11);
237
238 assert!(!less(vec![&left], vec![&right]));
239 assert!(less(vec![&right], vec![&left]));
240
241 let left = json!(-10.0);
242 let right = json!(-11.0);
243
244 assert!(!less(vec![&left], vec![&right]));
245 assert!(less(vec![&right], vec![&left]));
246
247 assert!(!less(vec![], vec![&right]));
248 assert!(!less(vec![&right, &right], vec![&left]));
249 }
250
251 #[test]
252 fn regex_test() {
253 let right = json!("[a-zA-Z]+[0-9]#[0-9]+");
254 let left1 = json!("a11#");
255 let left2 = json!("a1#1");
256 let left3 = json!("a#11");
257 let left4 = json!("#a11");
258
259 assert!(regex(
260 vec![&left1, &left2, &left3, &left4],
261 vec![&right],
262 &RegexCache::default()
263 ));
264 assert!(!regex(
265 vec![&left1, &left3, &left4],
266 vec![&right],
267 &RegexCache::default()
268 ))
269 }
270
271 #[test]
272 fn any_of_test() {
273 let right = json!([1, 2, 3, 4, 5, 6]);
274 let left = json!([1, 100, 101]);
275 assert!(any_of(vec![&left], vec![&right]));
276
277 let left = json!([11, 100, 101]);
278 assert!(!any_of(vec![&left], vec![&right]));
279
280 let left1 = json!(1);
281 let left2 = json!(11);
282 assert!(any_of(vec![&left1, &left2], vec![&right]));
283 }
284
285 #[test]
286 fn sub_set_of_test() {
287 let left1 = json!(1);
288 let left2 = json!(2);
289 let left3 = json!(3);
290 let left40 = json!(40);
291 let right = json!([1, 2, 3, 4, 5, 6]);
292 assert!(sub_set_of(
293 vec![&Value::Array(vec![
294 left1.clone(),
295 left2.clone(),
296 left3.clone(),
297 ])],
298 vec![&right],
299 ));
300 assert!(!sub_set_of(
301 vec![&Value::Array(vec![left1, left2, left3, left40])],
302 vec![&right],
303 ));
304 }
305
306 #[test]
307 fn size_test() {
308 let left1 = json!("abc");
309 let left2 = json!([1, 2, 3]);
310 let left3 = json!([1, 2, 3, 4]);
311 let right = json!(3);
312 assert!(size(vec![&left1], vec![&right]));
313 assert!(size(vec![&left2], vec![&right]));
314 assert!(!size(vec![&left3], vec![&right]));
315 }
316}