1use crate::path::json_path_instance;
2use crate::path::JsonLike;
3use crate::JsonPathValue;
4use crate::JsonPtr;
5use crate::{JsonPath, JsonPathStr};
6
7impl<T> JsonPath<T>
8where
9 T: JsonLike,
10{
11 pub fn find_slice<'a>(&'a self, json: &'a T) -> Vec<JsonPathValue<'a, T>> {
35 use crate::path::Path;
36 let instance = json_path_instance(self, json);
37 let res = instance.find(JsonPathValue::from_root(json));
38 let has_v: Vec<JsonPathValue<'_, T>> = res.into_iter().filter(|v| v.has_value()).collect();
39
40 if has_v.is_empty() {
41 vec![JsonPathValue::NoValue]
42 } else {
43 has_v
44 }
45 }
46
47 pub fn find_slice_ptr<'a>(&'a self, json: &'a T) -> Vec<JsonPtr<'a, T>> {
50 use crate::path::Path;
51 json_path_instance(self, json)
52 .find(JsonPathValue::from_root(json))
53 .into_iter()
54 .filter(|v| v.has_value())
55 .map(|v| match v {
56 JsonPathValue::Slice(v, _) => JsonPtr::Slice(v),
57 JsonPathValue::NewValue(v) => JsonPtr::NewValue(v),
58 JsonPathValue::NoValue => unreachable!("has_value was already checked"),
59 })
60 .collect()
61 }
62
63 pub fn find(&self, json: &T) -> T {
81 let slice = self.find_slice(json);
82 if !slice.is_empty() {
83 if JsonPathValue::only_no_value(&slice) {
84 T::null()
85 } else {
86 T::array(
87 slice
88 .into_iter()
89 .filter(|v| v.has_value())
90 .map(|v| v.to_data())
91 .collect(),
92 )
93 }
94 } else {
95 T::array(vec![])
96 }
97 }
98
99 pub fn find_as_path(&self, json: &T) -> Vec<JsonPathStr> {
119 self.find_slice(json)
120 .into_iter()
121 .flat_map(|v| v.to_path())
122 .collect()
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use crate::path::JsonLike;
129 use crate::JsonPathQuery;
130 use crate::JsonPathValue::{NoValue, Slice};
131 use crate::{jp_v, JsonPath, JsonPathParserError, JsonPathValue};
132 use serde_json::{json, Value};
133 use std::ops::Deref;
134
135 fn test(json: &str, path: &str, expected: Vec<JsonPathValue<Value>>) {
136 let json: Value = match serde_json::from_str(json) {
137 Ok(json) => json,
138 Err(e) => panic!("error while parsing json: {}", e),
139 };
140 let path = match JsonPath::try_from(path) {
141 Ok(path) => path,
142 Err(e) => panic!("error while parsing jsonpath: {}", e),
143 };
144
145 assert_eq!(path.find_slice(&json), expected)
146 }
147
148 fn template_json<'a>() -> &'a str {
149 r#" {"store": { "book": [
150 {
151 "category": "reference",
152 "author": "Nigel Rees",
153 "title": "Sayings of the Century",
154 "price": 8.95
155 },
156 {
157 "category": "fiction",
158 "author": "Evelyn Waugh",
159 "title": "Sword of Honour",
160 "price": 12.99
161 },
162 {
163 "category": "fiction",
164 "author": "Herman Melville",
165 "title": "Moby Dick",
166 "isbn": "0-553-21311-3",
167 "price": 8.99
168 },
169 {
170 "category": "fiction",
171 "author": "J. R. R. Tolkien",
172 "title": "The Lord of the Rings",
173 "isbn": "0-395-19395-8",
174 "price": 22.99
175 }
176 ],
177 "bicycle": {
178 "color": "red",
179 "price": 19.95
180 }
181 },
182 "array":[0,1,2,3,4,5,6,7,8,9],
183 "orders":[
184 {
185 "ref":[1,2,3],
186 "id":1,
187 "filled": true
188 },
189 {
190 "ref":[4,5,6],
191 "id":2,
192 "filled": false
193 },
194 {
195 "ref":[7,8,9],
196 "id":3,
197 "filled": null
198 }
199 ],
200 "expensive": 10 }"#
201 }
202
203 #[test]
204 fn simple_test() {
205 let j1 = json!(2);
206 test("[1,2,3]", "$[1]", jp_v![&j1;"$[1]",]);
207 }
208
209 #[test]
210 fn root_test() {
211 let js = serde_json::from_str(template_json()).unwrap();
212 test(template_json(), "$", jp_v![&js;"$",]);
213 }
214
215 #[test]
216 fn descent_test() {
217 let v1 = json!("reference");
218 let v2 = json!("fiction");
219 test(
220 template_json(),
221 "$..category",
222 jp_v![
223 &v1;"$.['store'].['book'][0].['category']",
224 &v2;"$.['store'].['book'][1].['category']",
225 &v2;"$.['store'].['book'][2].['category']",
226 &v2;"$.['store'].['book'][3].['category']",],
227 );
228 let js1 = json!(19.95);
229 let js2 = json!(8.95);
230 let js3 = json!(12.99);
231 let js4 = json!(8.99);
232 let js5 = json!(22.99);
233 test(
234 template_json(),
235 "$.store..price",
236 jp_v![
237 &js1;"$.['store'].['bicycle'].['price']",
238 &js2;"$.['store'].['book'][0].['price']",
239 &js3;"$.['store'].['book'][1].['price']",
240 &js4;"$.['store'].['book'][2].['price']",
241 &js5;"$.['store'].['book'][3].['price']",
242 ],
243 );
244 let js1 = json!("Nigel Rees");
245 let js2 = json!("Evelyn Waugh");
246 let js3 = json!("Herman Melville");
247 let js4 = json!("J. R. R. Tolkien");
248 test(
249 template_json(),
250 "$..author",
251 jp_v![
252 &js1;"$.['store'].['book'][0].['author']",
253 &js2;"$.['store'].['book'][1].['author']",
254 &js3;"$.['store'].['book'][2].['author']",
255 &js4;"$.['store'].['book'][3].['author']",],
256 );
257 }
258
259 #[test]
260 fn wildcard_test() {
261 let js1 = json!("reference");
262 let js2 = json!("fiction");
263 test(
264 template_json(),
265 "$..book.[*].category",
266 jp_v![
267 &js1;"$.['store'].['book'][0].['category']",
268 &js2;"$.['store'].['book'][1].['category']",
269 &js2;"$.['store'].['book'][2].['category']",
270 &js2;"$.['store'].['book'][3].['category']",],
271 );
272 let js1 = json!("Nigel Rees");
273 let js2 = json!("Evelyn Waugh");
274 let js3 = json!("Herman Melville");
275 let js4 = json!("J. R. R. Tolkien");
276 test(
277 template_json(),
278 "$.store.book[*].author",
279 jp_v![
280 &js1;"$.['store'].['book'][0].['author']",
281 &js2;"$.['store'].['book'][1].['author']",
282 &js3;"$.['store'].['book'][2].['author']",
283 &js4;"$.['store'].['book'][3].['author']",],
284 );
285 }
286
287 #[test]
288 fn descendent_wildcard_test() {
289 let js1 = json!("Moby Dick");
290 let js2 = json!("The Lord of the Rings");
291 test(
292 template_json(),
293 "$..*.[?(@.isbn)].title",
294 jp_v![
295 &js1;"$.['store'].['book'][2].['title']",
296 &js2;"$.['store'].['book'][3].['title']",
297 &js1;"$.['store'].['book'][2].['title']",
298 &js2;"$.['store'].['book'][3].['title']"],
299 );
300 }
301
302 #[test]
303 fn field_test() {
304 let value = json!({"active":1});
305 test(
306 r#"{"field":{"field":[{"active":1},{"passive":1}]}}"#,
307 "$.field.field[?(@.active)]",
308 jp_v![&value;"$.['field'].['field'][0]",],
309 );
310 }
311
312 #[test]
313 fn index_index_test() {
314 let value = json!("0-553-21311-3");
315 test(
316 template_json(),
317 "$..book[2].isbn",
318 jp_v![&value;"$.['store'].['book'][2].['isbn']",],
319 );
320 }
321
322 #[test]
323 fn index_unit_index_test() {
324 let value = json!("0-553-21311-3");
325 test(
326 template_json(),
327 "$..book[2,4].isbn",
328 jp_v![&value;"$.['store'].['book'][2].['isbn']",],
329 );
330 let value1 = json!("0-395-19395-8");
331 test(
332 template_json(),
333 "$..book[2,3].isbn",
334 jp_v![&value;"$.['store'].['book'][2].['isbn']", &value1;"$.['store'].['book'][3].['isbn']",],
335 );
336 }
337
338 #[test]
339 fn index_unit_keys_test() {
340 let js1 = json!("Moby Dick");
341 let js2 = json!(8.99);
342 let js3 = json!("The Lord of the Rings");
343 let js4 = json!(22.99);
344 test(
345 template_json(),
346 "$..book[2,3]['title','price']",
347 jp_v![
348 &js1;"$.['store'].['book'][2].['title']",
349 &js2;"$.['store'].['book'][2].['price']",
350 &js3;"$.['store'].['book'][3].['title']",
351 &js4;"$.['store'].['book'][3].['price']",],
352 );
353 }
354
355 #[test]
356 fn index_slice_test() {
357 let i0 = "$.['array'][0]";
358 let i1 = "$.['array'][1]";
359 let i2 = "$.['array'][2]";
360 let i3 = "$.['array'][3]";
361 let i4 = "$.['array'][4]";
362 let i5 = "$.['array'][5]";
363 let i6 = "$.['array'][6]";
364 let i7 = "$.['array'][7]";
365 let i8 = "$.['array'][8]";
366 let i9 = "$.['array'][9]";
367
368 let j0 = json!(0);
369 let j1 = json!(1);
370 let j2 = json!(2);
371 let j3 = json!(3);
372 let j4 = json!(4);
373 let j5 = json!(5);
374 let j6 = json!(6);
375 let j7 = json!(7);
376 let j8 = json!(8);
377 let j9 = json!(9);
378 test(
379 template_json(),
380 "$.array[:]",
381 jp_v![
382 &j0;&i0,
383 &j1;&i1,
384 &j2;&i2,
385 &j3;&i3,
386 &j4;&i4,
387 &j5;&i5,
388 &j6;&i6,
389 &j7;&i7,
390 &j8;&i8,
391 &j9;&i9,],
392 );
393 test(template_json(), "$.array[1:4:2]", jp_v![&j1;&i1, &j3;&i3,]);
394 test(
395 template_json(),
396 "$.array[::3]",
397 jp_v![&j0;&i0, &j3;&i3, &j6;&i6, &j9;&i9,],
398 );
399 test(template_json(), "$.array[-1:]", jp_v![&j9;&i9,]);
400 test(template_json(), "$.array[-2:-1]", jp_v![&j8;&i8,]);
401 }
402
403 #[test]
404 fn index_filter_test() {
405 let moby = json!("Moby Dick");
406 let rings = json!("The Lord of the Rings");
407 test(
408 template_json(),
409 "$..book[?(@.isbn)].title",
410 jp_v![
411 &moby;"$.['store'].['book'][2].['title']",
412 &rings;"$.['store'].['book'][3].['title']",],
413 );
414 let sword = json!("Sword of Honour");
415 test(
416 template_json(),
417 "$..book[?(@.price != 8.95)].title",
418 jp_v![
419 &sword;"$.['store'].['book'][1].['title']",
420 &moby;"$.['store'].['book'][2].['title']",
421 &rings;"$.['store'].['book'][3].['title']",],
422 );
423 let sayings = json!("Sayings of the Century");
424 test(
425 template_json(),
426 "$..book[?(@.price == 8.95)].title",
427 jp_v![&sayings;"$.['store'].['book'][0].['title']",],
428 );
429 let js895 = json!(8.95);
430 test(
431 template_json(),
432 "$..book[?(@.author ~= '.*Rees')].price",
433 jp_v![&js895;"$.['store'].['book'][0].['price']",],
434 );
435 let js12 = json!(12.99);
436 let js899 = json!(8.99);
437 let js2299 = json!(22.99);
438 test(
439 template_json(),
440 "$..book[?(@.price >= 8.99)].price",
441 jp_v![
442 &js12;"$.['store'].['book'][1].['price']",
443 &js899;"$.['store'].['book'][2].['price']",
444 &js2299;"$.['store'].['book'][3].['price']",
445 ],
446 );
447 test(
448 template_json(),
449 "$..book[?(@.price > 8.99)].price",
450 jp_v![
451 &js12;"$.['store'].['book'][1].['price']",
452 &js2299;"$.['store'].['book'][3].['price']",],
453 );
454 test(
455 template_json(),
456 "$..book[?(@.price < 8.99)].price",
457 jp_v![&js895;"$.['store'].['book'][0].['price']",],
458 );
459 test(
460 template_json(),
461 "$..book[?(@.price <= 8.99)].price",
462 jp_v![
463 &js895;"$.['store'].['book'][0].['price']",
464 &js899;"$.['store'].['book'][2].['price']",
465 ],
466 );
467 test(
468 template_json(),
469 "$..book[?(@.price <= $.expensive)].price",
470 jp_v![
471 &js895;"$.['store'].['book'][0].['price']",
472 &js899;"$.['store'].['book'][2].['price']",
473 ],
474 );
475 test(
476 template_json(),
477 "$..book[?(@.price >= $.expensive)].price",
478 jp_v![
479 &js12;"$.['store'].['book'][1].['price']",
480 &js2299;"$.['store'].['book'][3].['price']",
481 ],
482 );
483 test(
484 template_json(),
485 "$..book[?(@.title in ['Moby Dick','Shmoby Dick','Big Dick','Dicks'])].price",
486 jp_v![&js899;"$.['store'].['book'][2].['price']",],
487 );
488 test(
489 template_json(),
490 "$..book[?(@.title nin ['Moby Dick','Shmoby Dick','Big Dick','Dicks'])].title",
491 jp_v![
492 &sayings;"$.['store'].['book'][0].['title']",
493 &sword;"$.['store'].['book'][1].['title']",
494 &rings;"$.['store'].['book'][3].['title']",],
495 );
496 test(
497 template_json(),
498 "$..book[?(@.author size 10)].title",
499 jp_v![&sayings;"$.['store'].['book'][0].['title']",],
500 );
501 let filled_true = json!(1);
502 test(
503 template_json(),
504 "$.orders[?(@.filled == true)].id",
505 jp_v![&filled_true;"$.['orders'][0].['id']",],
506 );
507 let filled_null = json!(3);
508 test(
509 template_json(),
510 "$.orders[?(@.filled == null)].id",
511 jp_v![&filled_null;"$.['orders'][2].['id']",],
512 );
513 }
514
515 #[test]
516 fn index_filter_sets_test() {
517 let j1 = json!(1);
518 test(
519 template_json(),
520 "$.orders[?(@.ref subsetOf [1,2,3,4])].id",
521 jp_v![&j1;"$.['orders'][0].['id']",],
522 );
523 let j2 = json!(2);
524 test(
525 template_json(),
526 "$.orders[?(@.ref anyOf [1,4])].id",
527 jp_v![&j1;"$.['orders'][0].['id']", &j2;"$.['orders'][1].['id']",],
528 );
529 let j3 = json!(3);
530 test(
531 template_json(),
532 "$.orders[?(@.ref noneOf [3,6])].id",
533 jp_v![&j3;"$.['orders'][2].['id']",],
534 );
535 }
536
537 #[test]
538 fn query_test() {
539 let json: Box<Value> = serde_json::from_str(template_json()).expect("to get json");
540 let v = json
541 .path("$..book[?(@.author size 10)].title")
542 .expect("the path is correct");
543 assert_eq!(v, json!(["Sayings of the Century"]));
544
545 let json: Value = serde_json::from_str(template_json()).expect("to get json");
546 let path = &json
547 .path("$..book[?(@.author size 10)].title")
548 .expect("the path is correct");
549
550 assert_eq!(path, &json!(["Sayings of the Century"]));
551 }
552
553 #[test]
554 fn find_slice_test() {
555 let json: Box<Value> = serde_json::from_str(template_json()).expect("to get json");
556 let path: Box<JsonPath<Value>> = Box::from(
557 JsonPath::try_from("$..book[?(@.author size 10)].title").expect("the path is correct"),
558 );
559 let v = path.find_slice(&json);
560 let js = json!("Sayings of the Century");
561 assert_eq!(v, jp_v![&js;"$.['store'].['book'][0].['title']",]);
562 }
563
564 #[test]
565 fn find_in_array_test() {
566 let json: Box<Value> = Box::new(json!([{"verb": "TEST"}, {"verb": "RUN"}]));
567 let path: Box<JsonPath<Value>> =
568 Box::from(JsonPath::try_from("$.[?(@.verb == 'TEST')]").expect("the path is correct"));
569 let v = path.find_slice(&json);
570 let js = json!({"verb":"TEST"});
571 assert_eq!(v, jp_v![&js;"$[0]",]);
572 }
573
574 #[test]
575 fn length_test() {
576 let json: Box<Value> =
577 Box::new(json!([{"verb": "TEST"},{"verb": "TEST"}, {"verb": "RUN"}]));
578 let path: Box<JsonPath<Value>> = Box::from(
579 JsonPath::try_from("$.[?(@.verb == 'TEST')].length()").expect("the path is correct"),
580 );
581 let v = path.find(&json);
582 let js = json!([2]);
583 assert_eq!(v, js);
584
585 let json: Box<Value> =
586 Box::new(json!([{"verb": "TEST"},{"verb": "TEST"}, {"verb": "RUN"}]));
587 let path: Box<JsonPath<Value>> =
588 Box::from(JsonPath::try_from("$.length()").expect("the path is correct"));
589 assert_eq!(path.find(&json), json!([3]));
590
591 let json: Box<Value> =
593 Box::new(json!([{"verb": "TEST"},{"verb": "TEST","x":3}, {"verb": "RUN"}]));
594 let path: Box<JsonPath<Value>> = Box::from(
595 JsonPath::try_from("$.[?(@.verb == 'TEST')].[*].length()")
596 .expect("the path is correct"),
597 );
598 assert_eq!(path.find(&json), json!([3]));
599
600 let json: Box<Value> = Box::new(json!({"verb": "TEST"}));
602 let path: Box<JsonPath<Value>> =
603 Box::from(JsonPath::try_from("$.length()").expect("the path is correct"));
604 assert_eq!(path.find(&json), Value::Null);
605
606 let json: Box<Value> = Box::new(json!(1));
608 let path: Box<JsonPath<Value>> =
609 Box::from(JsonPath::try_from("$.length()").expect("the path is correct"));
610 assert_eq!(path.find(&json), Value::Null);
611
612 let json: Box<Value> = Box::new(json!([[1], [2], [3]]));
614 let path: Box<JsonPath<Value>> =
615 Box::from(JsonPath::try_from("$.length()").expect("the path is correct"));
616 assert_eq!(path.find(&json), json!([3]));
617
618 let json: Box<Value> =
620 Box::new(json!([{"verb": "TEST"},{"verb": "TEST"}, {"verb": "RUN"}]));
621 let path: Box<JsonPath<Value>> =
622 Box::from(JsonPath::try_from("$.not.exist.length()").expect("the path is correct"));
623 assert_eq!(path.find(&json), Value::Null);
624
625 let json: Box<Value> =
627 Box::new(json!([{"verb": "TEST"},{"verb": "TEST"}, {"verb": "RUN"}]));
628 let path: Box<JsonPath<Value>> = Box::from(
629 JsonPath::try_from("$.[?(@.verb == 'RUN')].length()").expect("the path is correct"),
630 );
631
632 let v = path.find(&json);
633 let js = json!([1]);
634 assert_eq!(v, js);
635
636 let json: Box<Value> =
638 Box::new(json!([{"verb": "TEST"},{"verb": "TEST"}, {"verb": "RUN"}]));
639 let path: Box<JsonPath<Value>> = Box::from(
640 JsonPath::try_from("$.[?(@.verb == 'RUN')].key123.length()")
641 .expect("the path is correct"),
642 );
643
644 let v = path.find(&json);
645 let js = json!(null);
646 assert_eq!(v, js);
647
648 let json: Box<Value> =
650 Box::new(json!([{"verb": "TEST"},{"verb": "TEST"}, {"verb": "RUN"}]));
651 let path: Box<JsonPath<Value>> =
652 Box::from(JsonPath::try_from("$.[0].length()").expect("the path is correct"));
653
654 let v = path.find(&json);
655 let js = Value::Null;
656 assert_eq!(v, js);
657
658 let json: Box<Value> = Box::new(json!([{"prop": [["a", "b", "c"], "d"]}]));
660 let path: Box<JsonPath<Value>> = Box::from(
661 JsonPath::try_from("$.[?(@.prop)].prop.[0].length()").expect("the path is correct"),
662 );
663
664 let v = path.find(&json);
665 let js = json!([3]);
666 assert_eq!(v, js);
667
668 let json: Box<Value> = Box::new(json!([{"prop": [["a", "b", "c"], "d"]}]));
670 let path: Box<JsonPath<Value>> = Box::from(
671 JsonPath::try_from("$.[?(@.prop)].prop.[1].length()").expect("the path is correct"),
672 );
673
674 let v = path.find(&json);
675 let js = Value::Null;
676 assert_eq!(v, js);
677 }
678
679 #[test]
680 fn no_value_index_from_not_arr_filter_test() {
681 let json: Box<Value> = Box::new(json!({
682 "field":"field",
683 }));
684
685 let path: Box<JsonPath<Value>> =
686 Box::from(JsonPath::try_from("$.field[1]").expect("the path is correct"));
687 let v = path.find_slice(&json);
688 assert_eq!(v, vec![NoValue]);
689
690 let json: Box<Value> = Box::new(json!({
691 "field":[0],
692 }));
693
694 let path: Box<JsonPath<Value>> =
695 Box::from(JsonPath::try_from("$.field[1]").expect("the path is correct"));
696 let v = path.find_slice(&json);
697 assert_eq!(v, vec![NoValue]);
698 }
699
700 #[test]
701 fn no_value_filter_from_not_arr_filter_test() {
702 let json: Box<Value> = Box::new(json!({
703 "field":"field",
704 }));
705
706 let path: Box<JsonPath<Value>> =
707 Box::from(JsonPath::try_from("$.field[?(@ == 0)]").expect("the path is correct"));
708 let v = path.find_slice(&json);
709 assert_eq!(v, vec![NoValue]);
710 }
711
712 #[test]
713 fn no_value_index_filter_test() {
714 let json: Box<Value> = Box::new(json!({
715 "field":[{"f":1},{"f":0}],
716 }));
717
718 let path: Box<JsonPath<Value>> =
719 Box::from(JsonPath::try_from("$.field[?(@.f_ == 0)]").expect("the path is correct"));
720 let v = path.find_slice(&json);
721 assert_eq!(v, vec![NoValue]);
722 }
723
724 #[test]
725 fn no_value_decent_test() {
726 let json: Box<Value> = Box::new(json!({
727 "field":[{"f":1},{"f":{"f_":1}}],
728 }));
729
730 let path: Box<JsonPath<Value>> =
731 Box::from(JsonPath::try_from("$..f_").expect("the path is correct"));
732 let v = path.find_slice(&json);
733 assert_eq!(
734 v,
735 vec![Slice(&json!(1), "$.['field'][1].['f'].['f_']".to_string())]
736 );
737 }
738
739 #[test]
740 fn no_value_chain_test() {
741 let json: Box<Value> = Box::new(json!({
742 "field":{"field":[1]},
743 }));
744
745 let path: Box<JsonPath<Value>> =
746 Box::from(JsonPath::try_from("$.field_.field").expect("the path is correct"));
747 let v = path.find_slice(&json);
748 assert_eq!(v, vec![NoValue]);
749
750 let path: Box<JsonPath<Value>> = Box::from(
751 JsonPath::try_from("$.field_.field[?(@ == 1)]").expect("the path is correct"),
752 );
753 let v = path.find_slice(&json);
754 assert_eq!(v, vec![NoValue]);
755 }
756
757 #[test]
758 fn no_value_filter_test() {
759 let json: Box<Value> =
761 Box::new(json!([{"verb": "TEST"},{"verb": "TEST"}, {"verb": "RUN"}]));
762 let path: Box<JsonPath<Value>> = Box::from(
763 JsonPath::try_from("$.[?(@.verb == \"RUN1\")]").expect("the path is correct"),
764 );
765 let v = path.find(&json);
766 let js = json!(null);
767 assert_eq!(v, js);
768 }
769
770 #[test]
771 fn no_value_len_test() {
772 let json: Box<Value> = Box::new(json!({
773 "field":{"field":1},
774 }));
775
776 let path: Box<JsonPath<Value>> =
777 Box::from(JsonPath::try_from("$.field.field.length()").expect("the path is correct"));
778 let v = path.find_slice(&json);
779 assert_eq!(v, vec![NoValue]);
780
781 let json: Box<Value> = Box::new(json!({
782 "field":[{"a":1},{"a":1}],
783 }));
784 let path: Box<JsonPath<Value>> = Box::from(
785 JsonPath::try_from("$.field[?(@.a == 0)].f.length()").expect("the path is correct"),
786 );
787 let v = path.find_slice(&json);
788 assert_eq!(v, vec![NoValue]);
789 }
790
791 #[test]
792 fn no_clone_api_test() {
793 fn test_coercion(value: &Value) -> Value {
794 value.clone()
795 }
796
797 let json: Value = serde_json::from_str(template_json()).expect("to get json");
798 let query =
799 JsonPath::try_from("$..book[?(@.author size 10)].title").expect("the path is correct");
800
801 let results = query.find_slice_ptr(&json);
802 let v = results.first().expect("to get value");
803
804 test_coercion(v);
806
807 assert_eq!(v.deref(), &json!("Sayings of the Century"));
809 }
810
811 #[test]
812 fn logical_exp_test() {
813 let json: Box<Value> = Box::new(json!({"first":{"second":[{"active":1},{"passive":1}]}}));
814
815 let path: Box<JsonPath<Value>> = Box::from(
816 JsonPath::try_from("$.first[?(@.does_not_exist && @.does_not_exist >= 1.0)]")
817 .expect("the path is correct"),
818 );
819 let v = path.find_slice(&json);
820 assert_eq!(v, vec![NoValue]);
821
822 let path: Box<JsonPath<Value>> = Box::from(
823 JsonPath::try_from("$.first[?(@.does_not_exist >= 1.0)]").expect("the path is correct"),
824 );
825 let v = path.find_slice(&json);
826 assert_eq!(v, vec![NoValue]);
827 }
828
829 #[test]
830 fn regex_filter_test() {
831 let json: Box<Value> = Box::new(json!({
832 "author":"abcd(Rees)",
833 }));
834
835 let path: Box<JsonPath<Value>> = Box::from(
836 JsonPath::try_from("$.[?(@.author ~= '(?i)d\\(Rees\\)')]")
837 .expect("the path is correct"),
838 );
839 assert_eq!(
840 path.find_slice(&json.clone()),
841 vec![Slice(&json!({"author":"abcd(Rees)"}), "$".to_string())]
842 );
843 }
844
845 #[test]
846 fn logical_not_exp_test() {
847 let json: Box<Value> = Box::new(json!({"first":{"second":{"active":1}}}));
848 let path: Box<JsonPath<Value>> = Box::from(
849 JsonPath::try_from("$.first[?(!@.does_not_exist >= 1.0)]")
850 .expect("the path is correct"),
851 );
852 let v = path.find_slice(&json);
853 assert_eq!(
854 v,
855 vec![Slice(
856 &json!({"second":{"active": 1}}),
857 "$.['first']".to_string()
858 )]
859 );
860
861 let path: Box<JsonPath<Value>> = Box::from(
862 JsonPath::try_from("$.first[?(!(@.does_not_exist >= 1.0))]")
863 .expect("the path is correct"),
864 );
865 let v = path.find_slice(&json);
866 assert_eq!(
867 v,
868 vec![Slice(
869 &json!({"second":{"active": 1}}),
870 "$.['first']".to_string()
871 )]
872 );
873
874 let path: Box<JsonPath<Value>> = Box::from(
875 JsonPath::try_from("$.first[?(!(@.second.active == 1) || @.second.active == 1)]")
876 .expect("the path is correct"),
877 );
878 let v = path.find_slice(&json);
879 assert_eq!(
880 v,
881 vec![Slice(
882 &json!({"second":{"active": 1}}),
883 "$.['first']".to_string()
884 )]
885 );
886
887 let path: Box<JsonPath<Value>> = Box::from(
888 JsonPath::try_from("$.first[?(!@.second.active == 1 && !@.second.active == 1 || !@.second.active == 2)]")
889 .expect("the path is correct"),
890 );
891 let v = path.find_slice(&json);
892 assert_eq!(
893 v,
894 vec![Slice(
895 &json!({"second":{"active": 1}}),
896 "$.['first']".to_string()
897 )]
898 );
899 }
900
901 #[test]
902 fn update_by_path_test() -> Result<(), JsonPathParserError> {
903 let mut json = json!([
904 {"verb": "RUN","distance":[1]},
905 {"verb": "TEST"},
906 {"verb": "DO NOT RUN"}
907 ]);
908
909 let path: Box<JsonPath> = Box::from(JsonPath::try_from("$.[?(@.verb == 'RUN')]")?);
910 let elem = path
911 .find_as_path(&json)
912 .first()
913 .cloned()
914 .ok_or(JsonPathParserError::InvalidJsonPath("".to_string()))?;
915
916 if let Some(v) = json
917 .reference_mut(elem)?
918 .and_then(|v| v.as_object_mut())
919 .and_then(|v| v.get_mut("distance"))
920 .and_then(|v| v.as_array_mut())
921 {
922 v.push(json!(2))
923 }
924
925 assert_eq!(
926 json,
927 json!([
928 {"verb": "RUN","distance":[1,2]},
929 {"verb": "TEST"},
930 {"verb": "DO NOT RUN"}
931 ])
932 );
933
934 Ok(())
935 }
936}