1use std::fmt::Debug;
2
3use crate::jsp_idx;
4use crate::parser::model::{FilterExpression, FilterSign, JsonPath};
5
6use crate::path::top::ObjectField;
7use crate::path::{json_path_instance, process_operand, JsonPathValue, Path, PathInstance};
8use crate::JsonPathValue::{NoValue, Slice};
9
10use super::{JsonLike, TopPaths};
11
12#[derive(Debug)]
14pub struct ArraySlice<T> {
15 start_index: i32,
16 end_index: i32,
17 step: usize,
18 _t: std::marker::PhantomData<T>,
19}
20
21impl<T> ArraySlice<T> {
22 pub(crate) fn new(start_index: i32, end_index: i32, step: usize) -> Self {
23 ArraySlice {
24 start_index,
25 end_index,
26 step,
27 _t: std::marker::PhantomData,
28 }
29 }
30
31 fn end(&self, len: i32) -> Option<usize> {
32 if self.end_index >= 0 {
33 if self.end_index > len {
34 None
35 } else {
36 Some(self.end_index as usize)
37 }
38 } else if self.end_index < -len {
39 None
40 } else {
41 Some((len - (-self.end_index)) as usize)
42 }
43 }
44
45 fn start(&self, len: i32) -> Option<usize> {
46 if self.start_index >= 0 {
47 if self.start_index > len {
48 None
49 } else {
50 Some(self.start_index as usize)
51 }
52 } else if self.start_index < -len {
53 None
54 } else {
55 Some((len - -self.start_index) as usize)
56 }
57 }
58
59 fn process<'a, F>(&self, elements: &'a [F]) -> Vec<(&'a F, usize)> {
60 let len = elements.len() as i32;
61 let mut filtered_elems: Vec<(&'a F, usize)> = vec![];
62 match (self.start(len), self.end(len)) {
63 (Some(start_idx), Some(end_idx)) => {
64 let end_idx = if end_idx == 0 {
65 elements.len()
66 } else {
67 end_idx
68 };
69 for idx in (start_idx..end_idx).step_by(self.step) {
70 if let Some(v) = elements.get(idx) {
71 filtered_elems.push((v, idx))
72 }
73 }
74 filtered_elems
75 }
76 _ => filtered_elems,
77 }
78 }
79}
80
81impl<'a, T> Path<'a> for ArraySlice<T>
82where
83 T: JsonLike,
84{
85 type Data = T;
86
87 fn find(&self, input: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
88 input.flat_map_slice(|data, pref| {
89 data.as_array()
90 .map(|elems| self.process(elems))
91 .and_then(|v| {
92 if v.is_empty() {
93 None
94 } else {
95 let v = v.into_iter().map(|(e, i)| (e, jsp_idx(&pref, i))).collect();
96 Some(JsonPathValue::map_vec(v))
97 }
98 })
99 .unwrap_or_else(|| vec![NoValue])
100 })
101 }
102}
103
104pub struct ArrayIndex<T> {
106 index: usize,
107 _t: std::marker::PhantomData<T>,
108}
109
110impl<T> ArrayIndex<T> {
111 pub(crate) fn new(index: usize) -> Self {
112 ArrayIndex {
113 index,
114 _t: std::marker::PhantomData,
115 }
116 }
117}
118
119impl<'a, T> Path<'a> for ArrayIndex<T>
120where
121 T: JsonLike,
122{
123 type Data = T;
124
125 fn find(&self, input: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
126 input.flat_map_slice(|data, pref| {
127 data.as_array()
128 .and_then(|elems| elems.get(self.index))
129 .map(|e| vec![JsonPathValue::new_slice(e, jsp_idx(&pref, self.index))])
130 .unwrap_or_else(|| vec![NoValue])
131 })
132 }
133}
134
135pub struct Current<'a, T> {
137 tail: Option<PathInstance<'a, T>>,
138 _t: std::marker::PhantomData<T>,
139}
140
141impl<'a, T> Current<'a, T>
142where
143 T: JsonLike,
144{
145 pub(crate) fn from(jp: &'a JsonPath<T>, root: &'a T) -> Self {
146 match jp {
147 JsonPath::Empty => Current::none(),
148 tail => Current::new(Box::new(json_path_instance(tail, root))),
149 }
150 }
151 pub(crate) fn new(tail: PathInstance<'a, T>) -> Self {
152 Current {
153 tail: Some(tail),
154 _t: std::marker::PhantomData,
155 }
156 }
157 pub(crate) fn none() -> Self {
158 Current {
159 tail: None,
160 _t: std::marker::PhantomData,
161 }
162 }
163}
164
165impl<'a, T> Path<'a> for Current<'a, T>
166where
167 T: JsonLike,
168{
169 type Data = T;
170
171 fn find(&self, input: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
172 self.tail
173 .as_ref()
174 .map(|p| p.find(input.clone()))
175 .unwrap_or_else(|| vec![input])
176 }
177}
178
179pub struct UnionIndex<'a, T> {
181 indexes: Vec<TopPaths<'a, T>>,
182}
183
184impl<'a, T> UnionIndex<'a, T>
185where
186 T: JsonLike,
187{
188 pub fn from_indexes(elems: &'a [T]) -> Self {
189 let mut indexes: Vec<TopPaths<'a, T>> = vec![];
190
191 for idx in elems.iter() {
192 indexes.push(TopPaths::ArrayIndex(ArrayIndex::new(
193 idx.as_u64().unwrap() as usize
194 )))
195 }
196
197 UnionIndex::new(indexes)
198 }
199 pub fn from_keys(elems: &'a [String]) -> Self {
200 let mut indexes: Vec<TopPaths<'a, T>> = vec![];
201
202 for key in elems.iter() {
203 indexes.push(TopPaths::ObjectField(ObjectField::new(key)))
204 }
205
206 UnionIndex::new(indexes)
207 }
208
209 pub fn new(indexes: Vec<TopPaths<'a, T>>) -> Self {
210 UnionIndex { indexes }
211 }
212}
213
214impl<'a, T> Path<'a> for UnionIndex<'a, T>
215where
216 T: JsonLike,
217{
218 type Data = T;
219
220 fn find(&self, input: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
221 self.indexes
222 .iter()
223 .flat_map(|e| e.find(input.clone()))
224 .collect()
225 }
226}
227
228pub enum FilterPath<'a, T> {
230 Filter {
231 left: PathInstance<'a, T>,
232 right: PathInstance<'a, T>,
233 op: &'a FilterSign,
234 },
235 Or {
236 left: PathInstance<'a, T>,
237 right: PathInstance<'a, T>,
238 },
239 And {
240 left: PathInstance<'a, T>,
241 right: PathInstance<'a, T>,
242 },
243 Not {
244 exp: PathInstance<'a, T>,
245 },
246}
247
248impl<'a, T> FilterPath<'a, T>
249where
250 T: JsonLike,
251{
252 pub(crate) fn new(expr: &'a FilterExpression<T>, root: &'a T) -> Self {
253 match expr {
254 FilterExpression::Atom(left, op, right) => FilterPath::Filter {
255 left: process_operand(left, root),
256 right: process_operand(right, root),
257 op,
258 },
259 FilterExpression::And(l, r) => FilterPath::And {
260 left: Box::new(FilterPath::new(l, root)),
261 right: Box::new(FilterPath::new(r, root)),
262 },
263 FilterExpression::Or(l, r) => FilterPath::Or {
264 left: Box::new(FilterPath::new(l, root)),
265 right: Box::new(FilterPath::new(r, root)),
266 },
267 FilterExpression::Not(exp) => FilterPath::Not {
268 exp: Box::new(FilterPath::new(exp, root)),
269 },
270 }
271 }
272 fn compound(
273 one: &'a FilterSign,
274 two: &'a FilterSign,
275 left: Vec<JsonPathValue<T>>,
276 right: Vec<JsonPathValue<T>>,
277 ) -> bool {
278 FilterPath::process_atom(one, left.clone(), right.clone())
279 || FilterPath::process_atom(two, left, right)
280 }
281 fn process_atom(
282 op: &'a FilterSign,
283 left: Vec<JsonPathValue<T>>,
284 right: Vec<JsonPathValue<T>>,
285 ) -> bool {
286 match op {
287 FilterSign::Equal => <T as JsonLike>::eq(
288 JsonPathValue::vec_as_data(left),
289 JsonPathValue::vec_as_data(right),
290 ),
291 FilterSign::Unequal => !FilterPath::process_atom(&FilterSign::Equal, left, right),
292 FilterSign::Less => <T as JsonLike>::less(
293 JsonPathValue::vec_as_data(left),
294 JsonPathValue::vec_as_data(right),
295 ),
296 FilterSign::LeOrEq => {
297 FilterPath::compound(&FilterSign::Less, &FilterSign::Equal, left, right)
298 }
299 FilterSign::Greater => <T as JsonLike>::less(
300 JsonPathValue::vec_as_data(right),
301 JsonPathValue::vec_as_data(left),
302 ),
303 FilterSign::GrOrEq => {
304 FilterPath::compound(&FilterSign::Greater, &FilterSign::Equal, left, right)
305 }
306 FilterSign::Regex => <T as JsonLike>::regex(
307 JsonPathValue::vec_as_data(left),
308 JsonPathValue::vec_as_data(right),
309 ),
310 FilterSign::In => <T as JsonLike>::inside(
311 JsonPathValue::vec_as_data(left),
312 JsonPathValue::vec_as_data(right),
313 ),
314 FilterSign::Nin => !FilterPath::process_atom(&FilterSign::In, left, right),
315 FilterSign::NoneOf => !FilterPath::process_atom(&FilterSign::AnyOf, left, right),
316 FilterSign::AnyOf => <T as JsonLike>::any_of(
317 JsonPathValue::vec_as_data(left),
318 JsonPathValue::vec_as_data(right),
319 ),
320 FilterSign::SubSetOf => <T as JsonLike>::sub_set_of(
321 JsonPathValue::vec_as_data(left),
322 JsonPathValue::vec_as_data(right),
323 ),
324 FilterSign::Exists => !JsonPathValue::vec_as_data(left).is_empty(),
325 FilterSign::Size => <T as JsonLike>::size(
326 JsonPathValue::vec_as_data(left),
327 JsonPathValue::vec_as_data(right),
328 ),
329 }
330 }
331
332 fn process(&self, curr_el: &'a T) -> bool {
333 let pref = String::new();
334 match self {
335 FilterPath::Filter { left, right, op } => FilterPath::process_atom(
336 op,
337 left.find(Slice(curr_el, pref.clone())),
338 right.find(Slice(curr_el, pref)),
339 ),
340 FilterPath::Or { left, right } => {
341 if !JsonPathValue::vec_as_data(left.find(Slice(curr_el, pref.clone()))).is_empty() {
342 true
343 } else {
344 !JsonPathValue::vec_as_data(right.find(Slice(curr_el, pref))).is_empty()
345 }
346 }
347 FilterPath::And { left, right } => {
348 if JsonPathValue::vec_as_data(left.find(Slice(curr_el, pref.clone()))).is_empty() {
349 false
350 } else {
351 !JsonPathValue::vec_as_data(right.find(Slice(curr_el, pref))).is_empty()
352 }
353 }
354 FilterPath::Not { exp } => {
355 JsonPathValue::vec_as_data(exp.find(Slice(curr_el, pref))).is_empty()
356 }
357 }
358 }
359}
360
361impl<'a, T> Path<'a> for FilterPath<'a, T>
362where
363 T: JsonLike,
364{
365 type Data = T;
366
367 fn find(&self, input: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
368 input.flat_map_slice(|data, pref| {
369 let mut res = vec![];
370 if data.is_array() {
371 let elems = data.as_array().unwrap();
372 for (i, el) in elems.iter().enumerate() {
373 if self.process(el) {
374 res.push(Slice(el, jsp_idx(&pref, i)))
375 }
376 }
377 } else if self.process(data) {
378 res.push(Slice(data, pref))
379 }
380
381 if res.is_empty() {
396 vec![NoValue]
397 } else {
398 res
399 }
400 })
401 }
402}
403
404#[cfg(test)]
405mod tests {
406 use crate::jp_v;
407 use crate::parser::macros::{chain, filter, idx, op};
408 use crate::parser::model::{FilterExpression, FilterSign, JsonPath, JsonPathIndex, Operand};
409 use crate::path::index::{ArrayIndex, ArraySlice};
410 use crate::path::JsonPathValue;
411 use crate::path::{json_path_instance, Path};
412 use crate::JsonPathValue::NoValue;
413
414 use crate::path;
415 use serde_json::{json, Value};
416
417 #[test]
418 fn array_slice_end_start_test() {
419 let array = [0, 1, 2, 3, 4, 5];
420 let len = array.len() as i32;
421 let mut slice: ArraySlice<Value> = ArraySlice::new(0, 0, 0);
422
423 assert_eq!(slice.start(len).unwrap(), 0);
424 slice.start_index = 1;
425
426 assert_eq!(slice.start(len).unwrap(), 1);
427
428 slice.start_index = 2;
429 assert_eq!(slice.start(len).unwrap(), 2);
430
431 slice.start_index = 5;
432 assert_eq!(slice.start(len).unwrap(), 5);
433
434 slice.start_index = 7;
435 assert_eq!(slice.start(len), None);
436
437 slice.start_index = -1;
438 assert_eq!(slice.start(len).unwrap(), 5);
439
440 slice.start_index = -5;
441 assert_eq!(slice.start(len).unwrap(), 1);
442
443 slice.end_index = 0;
444 assert_eq!(slice.end(len).unwrap(), 0);
445
446 slice.end_index = 5;
447 assert_eq!(slice.end(len).unwrap(), 5);
448
449 slice.end_index = -1;
450 assert_eq!(slice.end(len).unwrap(), 5);
451
452 slice.end_index = -5;
453 assert_eq!(slice.end(len).unwrap(), 1);
454 }
455
456 #[test]
457 fn slice_test() {
458 let array = json!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
459
460 let mut slice = ArraySlice::new(0, 6, 2);
461 let j1 = json!(0);
462 let j2 = json!(2);
463 let j4 = json!(4);
464 assert_eq!(
465 slice.find(JsonPathValue::new_slice(&array, "a".to_string())),
466 jp_v![&j1;"a[0]", &j2;"a[2]", &j4;"a[4]"]
467 );
468
469 slice.step = 3;
470 let j0 = json!(0);
471 let j3 = json!(3);
472 assert_eq!(slice.find(jp_v!(&array)), jp_v![&j0;"[0]", &j3;"[3]"]);
473
474 slice.start_index = -1;
475 slice.end_index = 1;
476
477 assert_eq!(
478 slice.find(JsonPathValue::new_slice(&array, "a".to_string())),
479 vec![NoValue]
480 );
481
482 slice.start_index = -10;
483 slice.end_index = 10;
484
485 let j1 = json!(1);
486 let j4 = json!(4);
487 let j7 = json!(7);
488
489 assert_eq!(
490 slice.find(JsonPathValue::new_slice(&array, "a".to_string())),
491 jp_v![&j1;"a[1]", &j4;"a[4]", &j7;"a[7]"]
492 );
493 }
494
495 #[test]
496 fn index_test() {
497 let array = json!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
498
499 let mut index = ArrayIndex::new(0);
500 let j0 = json!(0);
501 let j10 = json!(10);
502 assert_eq!(
503 index.find(JsonPathValue::new_slice(&array, "a".to_string())),
504 jp_v![&j0;"a[0]",]
505 );
506 index.index = 10;
507 assert_eq!(
508 index.find(JsonPathValue::new_slice(&array, "a".to_string())),
509 jp_v![&j10;"a[10]",]
510 );
511 index.index = 100;
512 assert_eq!(
513 index.find(JsonPathValue::new_slice(&array, "a".to_string())),
514 vec![NoValue]
515 );
516 }
517
518 #[test]
519 fn current_test() {
520 let json = json!(
521 {
522 "object":{
523 "field_1":[1,2,3],
524 "field_2":42,
525 "field_3":{"a":"b"}
526
527 }
528 });
529
530 let chain = chain!(path!($), path!("object"), path!(@));
531
532 let path_inst = json_path_instance(&chain, &json);
533 let res = json!({
534 "field_1":[1,2,3],
535 "field_2":42,
536 "field_3":{"a":"b"}
537 });
538
539 let expected_res = jp_v!(&res;"$.['object']",);
540 assert_eq!(path_inst.find(jp_v!(&json)), expected_res);
541
542 let cur = path!(@,path!("field_3"),path!("a"));
543 let chain = chain!(path!($), path!("object"), cur);
544
545 let path_inst = json_path_instance(&chain, &json);
546 let res1 = json!("b");
547
548 let expected_res = vec![JsonPathValue::new_slice(
549 &res1,
550 "$.['object'].['field_3'].['a']".to_string(),
551 )];
552 assert_eq!(path_inst.find(jp_v!(&json)), expected_res);
553 }
554
555 #[test]
556 fn filter_exist_test() {
557 let json = json!({
558 "threshold" : 3,
559 "key":[{"field":[1,2,3,4,5],"field1":[7]},{"field":42}],
560 });
561
562 let index = path!(idx!(?filter!(op!(path!(@, path!("field"))), "exists", op!())));
563 let chain = chain!(path!($), path!("key"), index, path!("field"));
564
565 let path_inst = json_path_instance(&chain, &json);
566
567 let exp1 = json!([1, 2, 3, 4, 5]);
568 let exp2 = json!(42);
569 let expected_res = jp_v!(&exp1;"$.['key'][0].['field']",&exp2;"$.['key'][1].['field']");
570 assert_eq!(path_inst.find(jp_v!(&json)), expected_res)
571 }
572
573 #[test]
574 fn filter_gr_test() {
575 let json = json!({
576 "threshold" : 4,
577 "key":[
578 {"field":1},
579 {"field":10},
580 {"field":4},
581 {"field":5},
582 {"field":1},
583 ]
584 });
585 let _exp1 = json!( {"field":10});
586 let _exp2 = json!( {"field":5});
587 let exp3 = json!( {"field":4});
588 let exp4 = json!( {"field":1});
589
590 let index = path!(
591 idx!(?filter!(op!(path!(@, path!("field"))), ">", op!(chain!(path!($), path!("threshold")))))
592 );
593
594 let chain = chain!(path!($), path!("key"), index);
595
596 let path_inst = json_path_instance(&chain, &json);
597
598 let exp1 = json!( {"field":10});
599 let exp2 = json!( {"field":5});
600 let expected_res = jp_v![&exp1;"$.['key'][1]", &exp2;"$.['key'][3]"];
601 assert_eq!(
602 path_inst.find(JsonPathValue::from_root(&json)),
603 expected_res
604 );
605 let expected_res = jp_v![&exp1;"$.['key'][1]", &exp2;"$.['key'][3]"];
606 assert_eq!(
607 path_inst.find(JsonPathValue::from_root(&json)),
608 expected_res
609 );
610
611 let index = path!(
612 idx!(?filter!(op!(path!(@, path!("field"))), ">=", op!(chain!(path!($), path!("threshold")))))
613 );
614 let chain = chain!(path!($), path!("key"), index);
615 let path_inst = json_path_instance(&chain, &json);
616 let expected_res = jp_v![
617 &exp1;"$.['key'][1]", &exp3;"$.['key'][2]", &exp2;"$.['key'][3]"];
618 assert_eq!(
619 path_inst.find(JsonPathValue::from_root(&json)),
620 expected_res
621 );
622
623 let index = path!(
624 idx!(?filter!(op!(path!(@, path!("field"))), "<", op!(chain!(path!($), path!("threshold")))))
625 );
626 let chain = chain!(path!($), path!("key"), index);
627 let path_inst = json_path_instance(&chain, &json);
628 let expected_res = jp_v![&exp4;"$.['key'][0]", &exp4;"$.['key'][4]"];
629 assert_eq!(
630 path_inst.find(JsonPathValue::from_root(&json)),
631 expected_res
632 );
633
634 let index = path!(
635 idx!(?filter!(op!(path!(@, path!("field"))), "<=", op!(chain!(path!($), path!("threshold")))))
636 );
637 let chain = chain!(path!($), path!("key"), index);
638 let path_inst = json_path_instance(&chain, &json);
639 let expected_res = jp_v![
640 &exp4;"$.['key'][0]",
641 &exp3;"$.['key'][2]",
642 &exp4;"$.['key'][4]"];
643 assert_eq!(
644 path_inst.find(JsonPathValue::from_root(&json)),
645 expected_res
646 );
647 }
648
649 #[test]
650 fn filter_regex_test() {
651 let json = json!({
652 "key":[
653 {"field":"a11#"},
654 {"field":"a1#1"},
655 {"field":"a#11"},
656 {"field":"#a11"},
657 ]
658 });
659
660 let index = idx!(?filter!(op!(path!(@,path!("field"))),"~=", op!("[a-zA-Z]+[0-9]#[0-9]+")));
661 let chain = chain!(path!($), path!("key"), path!(index));
662
663 let path_inst = json_path_instance(&chain, &json);
664
665 let exp2 = json!( {"field":"a1#1"});
666 let expected_res = jp_v![&exp2;"$.['key'][1]",];
667 assert_eq!(
668 path_inst.find(JsonPathValue::from_root(&json)),
669 expected_res
670 )
671 }
672
673 #[test]
674 fn filter_any_of_test() {
675 let json = json!({
676 "key":[
677 {"field":"a11#"},
678 {"field":"a1#1"},
679 {"field":"a#11"},
680 {"field":"#a11"},
681 ]
682 });
683
684 let index = idx!(?filter!(
685 op!(path!(@,path!("field"))),
686 "anyOf",
687 op!(s ["a11#","aaa","111"])
688 ));
689
690 let chain = chain!(path!($), JsonPath::Field(String::from("key")), path!(index));
691
692 let path_inst = json_path_instance(&chain, &json);
693
694 let exp2 = json!( {"field":"a11#"});
695 let expected_res = jp_v![&exp2;"$.['key'][0]",];
696 assert_eq!(
697 path_inst.find(JsonPathValue::from_root(&json)),
698 expected_res
699 )
700 }
701
702 #[test]
703 fn size_test() {
704 let json = json!({
705 "key":[
706 {"field":"aaaa"},
707 {"field":"bbb"},
708 {"field":"cc"},
709 {"field":"dddd"},
710 {"field":[1,1,1,1]},
711 ]
712 });
713
714 let index = idx!(?filter!(op!(path!(@, path!("field"))),"size",op!(4)));
715 let chain = chain!(path!($), path!("key"), path!(index));
716 let path_inst = json_path_instance(&chain, &json);
717
718 let f1 = json!( {"field":"aaaa"});
719 let f2 = json!( {"field":"dddd"});
720 let f3 = json!( {"field":[1,1,1,1]});
721
722 let expected_res = jp_v![&f1;"$.['key'][0]", &f2;"$.['key'][3]", &f3;"$.['key'][4]"];
723 assert_eq!(
724 path_inst.find(JsonPathValue::from_root(&json)),
725 expected_res
726 )
727 }
728
729 #[test]
730 fn nested_filter_test() {
731 let json = json!({
732 "obj":{
733 "id":1,
734 "not_id": 2,
735 "more_then_id" :3
736 }
737 });
738 let index = idx!(?filter!(
739 op!(path!(@,path!("not_id"))), "==",op!(2)
740 ));
741 let chain = chain!(path!($), path!("obj"), path!(index));
742 let path_inst = json_path_instance(&chain, &json);
743 let js = json!({
744 "id":1,
745 "not_id": 2,
746 "more_then_id" :3
747 });
748 assert_eq!(
749 path_inst.find(JsonPathValue::from_root(&json)),
750 jp_v![&js;"$.['obj']",]
751 )
752 }
753
754 #[test]
755 fn or_arr_test() {
756 let json = json!({
757 "key":[
758 {"city":"London","capital":true, "size": "big"},
759 {"city":"Berlin","capital":true,"size": "big"},
760 {"city":"Tokyo","capital":true,"size": "big"},
761 {"city":"Moscow","capital":true,"size": "big"},
762 {"city":"Athlon","capital":false,"size": "small"},
763 {"city":"Dortmund","capital":false,"size": "big"},
764 {"city":"Dublin","capital":true,"size": "small"},
765 ]
766 });
767 let index = idx!(?filter!(
768 filter!(op!(path!(@,path!("capital"))), "==", op!(false)),
769 ||,
770 filter!(op!(path!(@,path!("size"))), "==", op!("small"))
771 )
772 );
773 let chain = chain!(path!($), path!("key"), path!(index), path!("city"));
774 let path_inst = json_path_instance(&chain, &json);
775 let a = json!("Athlon");
776 let d = json!("Dortmund");
777 let dd = json!("Dublin");
778 assert_eq!(
779 path_inst.find(JsonPathValue::from_root(&json)),
780 jp_v![
781 &a;"$.['key'][4].['city']",
782 &d;"$.['key'][5].['city']",
783 ⅆ"$.['key'][6].['city']"]
784 )
785 }
786
787 #[test]
788 fn or_obj_test() {
789 let json = json!({
790 "key":{
791 "id":1,
792 "name":"a",
793 "another":"b"
794 }
795 });
796 let index = idx!(?filter!(
797 filter!(op!(path!(@,path!("name"))), "==", op!("a")),
798 ||,
799 filter!(op!(path!(@,path!("another"))), "==", op!("b"))
800 )
801 );
802 let chain = chain!(path!($), path!("key"), path!(index), path!("id"));
803 let path_inst = json_path_instance(&chain, &json);
804 let j1 = json!(1);
805 assert_eq!(
806 path_inst.find(JsonPathValue::from_root(&json)),
807 jp_v![&j1;"$.['key'].['id']",]
808 )
809 }
810
811 #[test]
812 fn or_obj_2_test() {
813 let json = json!({
814 "key":{
815 "id":1,
816 "name":"a",
817 "another":"d"
818 }
819 });
820 let index = idx!(?filter!(
821 filter!(op!(path!(@,path!("name"))), "==", op!("c")),
822 ||,
823 filter!(op!(path!(@,path!("another"))), "==", op!("d"))
824 )
825 );
826 let chain = chain!(path!($), path!("key"), path!(index), path!("id"));
827 let path_inst = json_path_instance(&chain, &json);
828 let j1 = json!(1);
829 assert_eq!(
830 path_inst.find(JsonPathValue::from_root(&json)),
831 jp_v![&j1;"$.['key'].['id']",]
832 )
833 }
834
835 #[test]
836 fn and_arr_test() {
837 let json = json!({
838 "key":[
839 {"city":"London","capital":true, "size": "big"},
840 {"city":"Berlin","capital":true,"size": "big"},
841 {"city":"Tokyo","capital":true,"size": "big"},
842 {"city":"Moscow","capital":true,"size": "big"},
843 {"city":"Athlon","capital":false,"size": "small"},
844 {"city":"Dortmund","capital":false,"size": "big"},
845 {"city":"Dublin","capital":true,"size": "small"},
846 ]
847 });
848 let index = idx!(?filter!(
849 filter!(op!(path!(@,path!("capital"))), "==", op!(false)),
850 &&,
851 filter!(op!(path!(@,path!("size"))), "==", op!("small"))
852 )
853 );
854 let chain = chain!(path!($), path!("key"), path!(index), path!("city"));
855 let path_inst = json_path_instance(&chain, &json);
856 let a = json!("Athlon");
857 let value = jp_v!( &a;"$.['key'][4].['city']",);
858 assert_eq!(path_inst.find(JsonPathValue::from_root(&json)), value)
859 }
860
861 #[test]
862 fn and_obj_test() {
863 let json = json!({
864 "key":{
865 "id":1,
866 "name":"a",
867 "another":"b"
868 }
869 });
870 let index = idx!(?filter!(
871 filter!(op!(path!(@,path!("name"))), "==", op!("a")),
872 &&,
873 filter!(op!(path!(@,path!("another"))), "==", op!("b"))
874 )
875 );
876 let chain = chain!(path!($), path!("key"), path!(index), path!("id"));
877 let path_inst = json_path_instance(&chain, &json);
878 let j1 = json!(1);
879 assert_eq!(
880 path_inst.find(JsonPathValue::from_root(&json)),
881 jp_v![&j1; "$.['key'].['id']",]
882 )
883 }
884
885 #[test]
886 fn and_obj_2_test() {
887 let json = json!({
888 "key":{
889 "id":1,
890 "name":"a",
891 "another":"d"
892 }
893 });
894 let index = idx!(?filter!(
895 filter!(op!(path!(@,path!("name"))), "==", op!("c")),
896 &&,
897 filter!(op!(path!(@,path!("another"))), "==", op!("d"))
898 )
899 );
900 let chain = chain!(path!($), path!("key"), path!(index), path!("id"));
901 let path_inst = json_path_instance(&chain, &json);
902 assert_eq!(
903 path_inst.find(JsonPathValue::from_root(&json)),
904 vec![NoValue]
905 )
906 }
907}