1use std::fmt::Debug;
2
3use crate::{jsp_idx, jsp_obj, JsonPathParserError, JsonPathStr, JsonPathValue};
4use regex::Regex;
5use serde_json::{json, Value};
6
7use crate::parser::model::{Function, JsonPath, JsonPathIndex, Operand};
8use crate::parser::parse_json_path;
9pub use crate::path::index::{ArrayIndex, ArraySlice, Current, FilterPath, UnionIndex};
10pub use crate::path::top::ObjectField;
11use crate::path::top::*;
12
13mod index;
15mod top;
17
18pub trait JsonLike:
28 Default
29 + Clone
30 + Debug
31 + for<'a> From<&'a str>
32 + From<Vec<String>>
33 + From<bool>
34 + From<i64>
35 + From<f64>
36 + From<Vec<Self>>
37 + From<String>
38 + PartialEq
39 + 'static
40{
41 fn get(&self, key: &str) -> Option<&Self>;
43
44 fn itre(&self, pref: String) -> Vec<JsonPathValue<'_, Self>>;
46
47 fn array_len(&self) -> JsonPathValue<'static, Self>;
49
50 fn init_with_usize(cnt: usize) -> Self;
52
53 fn deep_flatten(&self, pref: String) -> Vec<(&Self, String)>;
55
56 fn deep_path_by_key<'a>(
58 &'a self,
59 key: ObjectField<'a, Self>,
60 pref: String,
61 ) -> Vec<(&'a Self, String)>;
62
63 fn as_u64(&self) -> Option<u64>;
65
66 fn is_array(&self) -> bool;
68
69 fn as_array(&self) -> Option<&Vec<Self>>;
71
72 fn size(left: Vec<&Self>, right: Vec<&Self>) -> bool;
74
75 fn sub_set_of(left: Vec<&Self>, right: Vec<&Self>) -> bool;
77
78 fn any_of(left: Vec<&Self>, right: Vec<&Self>) -> bool;
80
81 fn regex(left: Vec<&Self>, right: Vec<&Self>) -> bool;
83
84 fn inside(left: Vec<&Self>, right: Vec<&Self>) -> bool;
86
87 fn less(left: Vec<&Self>, right: Vec<&Self>) -> bool;
89
90 fn eq(left: Vec<&Self>, right: Vec<&Self>) -> bool;
92
93 fn null() -> Self;
95
96 fn array(data: Vec<Self>) -> Self;
98
99 fn reference<T>(&self, path: T) -> Result<Option<&Self>, JsonPathParserError>
105 where
106 T: Into<JsonPathStr>;
107
108 fn reference_mut<T>(&mut self, path: T) -> Result<Option<&mut Self>, JsonPathParserError>
152 where
153 T: Into<JsonPathStr>;
154}
155
156impl JsonLike for Value {
157 fn get(&self, key: &str) -> Option<&Self> {
158 self.get(key)
159 }
160 fn itre(&self, pref: String) -> Vec<JsonPathValue<Self>> {
161 let res = match self {
162 Value::Array(elems) => {
163 let mut res = vec![];
164 for (idx, el) in elems.iter().enumerate() {
165 res.push(JsonPathValue::Slice(el, jsp_idx(&pref, idx)));
166 }
167 res
168 }
169 Value::Object(elems) => {
170 let mut res = vec![];
171 for (key, el) in elems.into_iter() {
172 res.push(JsonPathValue::Slice(el, jsp_obj(&pref, key)));
173 }
174 res
175 }
176 _ => vec![],
177 };
178 if res.is_empty() {
179 vec![JsonPathValue::NoValue]
180 } else {
181 res
182 }
183 }
184
185 fn array_len(&self) -> JsonPathValue<'static, Self> {
186 match self {
187 Value::Array(elems) => JsonPathValue::NewValue(json!(elems.len())),
188 _ => JsonPathValue::NoValue,
189 }
190 }
191
192 fn init_with_usize(cnt: usize) -> Self {
193 json!(cnt)
194 }
195
196 fn deep_flatten(&self, pref: String) -> Vec<(&Self, String)> {
197 let mut acc = vec![];
198 match self {
199 Value::Object(elems) => {
200 for (f, v) in elems.into_iter() {
201 let pref = jsp_obj(&pref, f);
202 acc.push((v, pref.clone()));
203 acc.append(&mut v.deep_flatten(pref));
204 }
205 }
206 Value::Array(elems) => {
207 for (i, v) in elems.iter().enumerate() {
208 let pref = jsp_idx(&pref, i);
209 acc.push((v, pref.clone()));
210 acc.append(&mut v.deep_flatten(pref));
211 }
212 }
213 _ => (),
214 }
215 acc
216 }
217
218 fn deep_path_by_key<'a>(
219 &'a self,
220 key: ObjectField<'a, Self>,
221 pref: String,
222 ) -> Vec<(&'a Self, String)> {
223 let mut result: Vec<(&'a Value, String)> =
224 JsonPathValue::vec_as_pair(key.find(JsonPathValue::new_slice(self, pref.clone())));
225 match self {
226 Value::Object(elems) => {
227 let mut next_levels: Vec<(&'a Value, String)> = elems
228 .into_iter()
229 .flat_map(|(k, v)| v.deep_path_by_key(key.clone(), jsp_obj(&pref, k)))
230 .collect();
231 result.append(&mut next_levels);
232 result
233 }
234 Value::Array(elems) => {
235 let mut next_levels: Vec<(&'a Value, String)> = elems
236 .iter()
237 .enumerate()
238 .flat_map(|(i, v)| v.deep_path_by_key(key.clone(), jsp_idx(&pref, i)))
239 .collect();
240 result.append(&mut next_levels);
241 result
242 }
243 _ => result,
244 }
245 }
246
247 fn as_u64(&self) -> Option<u64> {
248 self.as_u64()
249 }
250 fn is_array(&self) -> bool {
251 self.is_array()
252 }
253 fn as_array(&self) -> Option<&Vec<Self>> {
254 self.as_array()
255 }
256
257 fn size(left: Vec<&Self>, right: Vec<&Self>) -> bool {
258 if let Some(Value::Number(n)) = right.first() {
259 if let Some(sz) = n.as_f64() {
260 for el in left.iter() {
261 match el {
262 Value::String(v) if v.len() == sz as usize => true,
263 Value::Array(elems) if elems.len() == sz as usize => true,
264 Value::Object(fields) if fields.len() == sz as usize => true,
265 _ => return false,
266 };
267 }
268 return true;
269 }
270 }
271 false
272 }
273
274 fn sub_set_of(left: Vec<&Self>, right: Vec<&Self>) -> bool {
275 if left.is_empty() {
276 return true;
277 }
278 if right.is_empty() {
279 return false;
280 }
281
282 if let Some(elems) = left.first().and_then(|e| e.as_array()) {
283 if let Some(Value::Array(right_elems)) = right.first() {
284 if right_elems.is_empty() {
285 return false;
286 }
287
288 for el in elems {
289 let mut res = false;
290
291 for r in right_elems.iter() {
292 if el.eq(r) {
293 res = true
294 }
295 }
296 if !res {
297 return false;
298 }
299 }
300 return true;
301 }
302 }
303 false
304 }
305
306 fn any_of(left: Vec<&Self>, right: Vec<&Self>) -> bool {
307 if left.is_empty() {
308 return true;
309 }
310 if right.is_empty() {
311 return false;
312 }
313
314 if let Some(Value::Array(elems)) = right.first() {
315 if elems.is_empty() {
316 return false;
317 }
318
319 for el in left.iter() {
320 if let Some(left_elems) = el.as_array() {
321 for l in left_elems.iter() {
322 for r in elems.iter() {
323 if l.eq(r) {
324 return true;
325 }
326 }
327 }
328 } else {
329 for r in elems.iter() {
330 if el.eq(&r) {
331 return true;
332 }
333 }
334 }
335 }
336 }
337
338 false
339 }
340
341 fn regex(left: Vec<&Self>, right: Vec<&Self>) -> bool {
342 if left.is_empty() || right.is_empty() {
343 return false;
344 }
345
346 match right.first() {
347 Some(Value::String(str)) => {
348 if let Ok(regex) = Regex::new(str) {
349 for el in left.iter() {
350 if let Some(v) = el.as_str() {
351 if regex.is_match(v) {
352 return true;
353 }
354 }
355 }
356 }
357 false
358 }
359 _ => false,
360 }
361 }
362
363 fn inside(left: Vec<&Self>, right: Vec<&Self>) -> bool {
364 if left.is_empty() {
365 return false;
366 }
367
368 match right.first() {
369 Some(Value::Array(elems)) => {
370 for el in left.iter() {
371 if elems.contains(el) {
372 return true;
373 }
374 }
375 false
376 }
377 Some(Value::Object(elems)) => {
378 for el in left.iter() {
379 for r in elems.values() {
380 if el.eq(&r) {
381 return true;
382 }
383 }
384 }
385 false
386 }
387 _ => false,
388 }
389 }
390
391 fn less(left: Vec<&Self>, right: Vec<&Self>) -> bool {
393 if left.len() == 1 && right.len() == 1 {
394 match (left.first(), right.first()) {
395 (Some(Value::Number(l)), Some(Value::Number(r))) => l
396 .as_f64()
397 .and_then(|v1| r.as_f64().map(|v2| v1 < v2))
398 .unwrap_or(false),
399 _ => false,
400 }
401 } else {
402 false
403 }
404 }
405
406 fn eq(left: Vec<&Self>, right: Vec<&Self>) -> bool {
408 if left.len() != right.len() {
409 false
410 } else {
411 left.iter().zip(right).map(|(a, b)| a.eq(&b)).all(|a| a)
412 }
413 }
414
415 fn null() -> Self {
416 Value::Null
417 }
418
419 fn array(data: Vec<Self>) -> Self {
420 Value::Array(data)
421 }
422
423 fn reference<T>(&self, path: T) -> Result<Option<&Self>, JsonPathParserError>
424 where
425 T: Into<JsonPathStr>,
426 {
427 Ok(self.pointer(&path_to_json_path(path.into())?))
428 }
429
430 fn reference_mut<T>(&mut self, path: T) -> Result<Option<&mut Self>, JsonPathParserError>
431 where
432 T: Into<JsonPathStr>,
433 {
434 Ok(self.pointer_mut(&path_to_json_path(path.into())?))
435 }
436}
437
438fn path_to_json_path(path: JsonPathStr) -> Result<String, JsonPathParserError> {
439 convert_part(&parse_json_path::<Value>(path.as_str())?)
440}
441
442fn convert_part(path: &JsonPath) -> Result<String, JsonPathParserError> {
443 match path {
444 JsonPath::Chain(elems) => elems
445 .iter()
446 .map(convert_part)
447 .collect::<Result<String, JsonPathParserError>>(),
448
449 JsonPath::Index(JsonPathIndex::Single(v)) => Ok(format!("/{}", v)),
450 JsonPath::Field(e) => Ok(format!("/{}", e)),
451 JsonPath::Root => Ok("".to_string()),
452 e => Err(JsonPathParserError::InvalidJsonPath(e.to_string())),
453 }
454}
455
456pub trait Path<'a> {
461 type Data;
462 fn find(&self, input: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
464 vec![input]
465 }
466 fn flat_find(
468 &self,
469 input: Vec<JsonPathValue<'a, Self::Data>>,
470 _is_search_length: bool,
471 ) -> Vec<JsonPathValue<'a, Self::Data>> {
472 input.into_iter().flat_map(|d| self.find(d)).collect()
473 }
474 fn needs_all(&self) -> bool {
476 false
477 }
478}
479
480pub enum TopPaths<'a, T> {
482 RootPointer(RootPointer<'a, T>),
483 ObjectField(ObjectField<'a, T>),
484 Chain(Chain<'a, T>),
485 Wildcard(Wildcard<T>),
486 DescentObject(DescentObject<'a, T>),
487 DescentWildcard(DescentWildcard<T>),
488 Current(Current<'a, T>),
489 ArrayIndex(ArrayIndex<T>),
490 ArraySlice(ArraySlice<T>),
491 UnionIndex(UnionIndex<'a, T>),
492 FilterPath(FilterPath<'a, T>),
493 IdentityPath(IdentityPath<T>),
494 FnPath(FnPath<T>),
495}
496
497impl<'a, T> Path<'a> for TopPaths<'a, T>
498where
499 T: JsonLike,
500{
501 type Data = T;
502
503 fn find(&self, input: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
504 match self {
505 TopPaths::RootPointer(inner) => inner.find(input),
506 TopPaths::ObjectField(inner) => inner.find(input),
507 TopPaths::Chain(inner) => inner.find(input),
508 TopPaths::Wildcard(inner) => inner.find(input),
509 TopPaths::DescentObject(inner) => inner.find(input),
510 TopPaths::DescentWildcard(inner) => inner.find(input),
511 TopPaths::Current(inner) => inner.find(input),
512 TopPaths::ArrayIndex(inner) => inner.find(input),
513 TopPaths::ArraySlice(inner) => inner.find(input),
514 TopPaths::UnionIndex(inner) => inner.find(input),
515 TopPaths::FilterPath(inner) => inner.find(input),
516 TopPaths::IdentityPath(inner) => inner.find(input),
517 TopPaths::FnPath(inner) => inner.find(input),
518 }
519 }
520
521 fn flat_find(
522 &self,
523 input: Vec<JsonPathValue<'a, Self::Data>>,
524 _is_search_length: bool,
525 ) -> Vec<JsonPathValue<'a, Self::Data>> {
526 match self {
527 TopPaths::RootPointer(inner) => inner.flat_find(input, _is_search_length),
528 TopPaths::ObjectField(inner) => inner.flat_find(input, _is_search_length),
529 TopPaths::Chain(inner) => inner.flat_find(input, _is_search_length),
530 TopPaths::Wildcard(inner) => inner.flat_find(input, _is_search_length),
531 TopPaths::DescentObject(inner) => inner.flat_find(input, _is_search_length),
532 TopPaths::DescentWildcard(inner) => inner.flat_find(input, _is_search_length),
533 TopPaths::Current(inner) => inner.flat_find(input, _is_search_length),
534 TopPaths::ArrayIndex(inner) => inner.flat_find(input, _is_search_length),
535 TopPaths::ArraySlice(inner) => inner.flat_find(input, _is_search_length),
536 TopPaths::UnionIndex(inner) => inner.flat_find(input, _is_search_length),
537 TopPaths::FilterPath(inner) => inner.flat_find(input, _is_search_length),
538 TopPaths::IdentityPath(inner) => inner.flat_find(input, _is_search_length),
539 TopPaths::FnPath(inner) => inner.flat_find(input, _is_search_length),
540 }
541 }
542
543 fn needs_all(&self) -> bool {
544 match self {
545 TopPaths::RootPointer(inner) => inner.needs_all(),
546 TopPaths::ObjectField(inner) => inner.needs_all(),
547 TopPaths::Chain(inner) => inner.needs_all(),
548 TopPaths::Wildcard(inner) => inner.needs_all(),
549 TopPaths::DescentObject(inner) => inner.needs_all(),
550 TopPaths::DescentWildcard(inner) => inner.needs_all(),
551 TopPaths::Current(inner) => inner.needs_all(),
552 TopPaths::ArrayIndex(inner) => inner.needs_all(),
553 TopPaths::ArraySlice(inner) => inner.needs_all(),
554 TopPaths::UnionIndex(inner) => inner.needs_all(),
555 TopPaths::FilterPath(inner) => inner.needs_all(),
556 TopPaths::IdentityPath(inner) => inner.needs_all(),
557 TopPaths::FnPath(inner) => inner.needs_all(),
558 }
559 }
560}
561
562pub(crate) type PathInstance<'a, T> = Box<dyn Path<'a, Data = T> + 'a>;
564
565pub(crate) fn json_path_instance<'a, T>(json_path: &'a JsonPath<T>, root: &'a T) -> TopPaths<'a, T>
567where
568 T: JsonLike,
569{
570 match json_path {
571 JsonPath::Root => TopPaths::RootPointer(RootPointer::new(root)),
572 JsonPath::Field(key) => TopPaths::ObjectField(ObjectField::new(key)),
573 JsonPath::Chain(chain) => TopPaths::Chain(Chain::from(chain, root)),
574 JsonPath::Wildcard => TopPaths::Wildcard(Wildcard::new()),
575 JsonPath::Descent(key) => TopPaths::DescentObject(DescentObject::new(key)),
576 JsonPath::DescentW => TopPaths::DescentWildcard(DescentWildcard::new()),
577 JsonPath::Current(value) => TopPaths::Current(Current::from(value, root)),
578 JsonPath::Index(JsonPathIndex::Single(index)) => {
579 TopPaths::ArrayIndex(ArrayIndex::new(index.as_u64().unwrap() as usize))
580 }
581 JsonPath::Index(JsonPathIndex::Slice(s, e, step)) => {
582 TopPaths::ArraySlice(ArraySlice::new(*s, *e, *step))
583 }
584 JsonPath::Index(JsonPathIndex::UnionKeys(elems)) => {
585 TopPaths::UnionIndex(UnionIndex::from_keys(elems))
586 }
587 JsonPath::Index(JsonPathIndex::UnionIndex(elems)) => {
588 TopPaths::UnionIndex(UnionIndex::from_indexes(elems))
589 }
590 JsonPath::Index(JsonPathIndex::Filter(fe)) => {
591 TopPaths::FilterPath(FilterPath::new(fe, root))
592 }
593 JsonPath::Empty => TopPaths::IdentityPath(IdentityPath::new()),
594 JsonPath::Fn(Function::Length) => TopPaths::FnPath(FnPath::new_size()),
595 }
596}
597
598fn process_operand<'a, T>(op: &'a Operand<T>, root: &'a T) -> PathInstance<'a, T>
600where
601 T: JsonLike,
602{
603 Box::new(match op {
604 Operand::Static(v) => json_path_instance(&JsonPath::Root, v),
605 Operand::Dynamic(jp) => json_path_instance(jp, root),
606 })
607}
608
609#[cfg(test)]
610mod tests {
611 use crate::path::JsonPathIndex;
612 use crate::path::{convert_part, JsonLike};
613 use crate::{idx, path, JsonPath, JsonPathParserError};
614 use serde_json::{json, Value};
615
616 #[test]
617 fn value_eq_test() {
618 let left = json!({"value":42});
619 let right = json!({"value":42});
620 let right_uneq = json!([42]);
621 assert!(&left.eq(&right));
622 assert!(!&left.eq(&right_uneq));
623 }
624
625 #[test]
626 fn vec_value_test() {
627 let left = json!({"value":42});
628 let left1 = json!(42);
629 let left2 = json!([1, 2, 3]);
630 let left3 = json!({"value2":[42],"value":[42]});
631
632 let right = json!({"value":42});
633 let right1 = json!(42);
634 let right2 = json!([1, 2, 3]);
635 let right3 = json!({"value":[42],"value2":[42]});
636
637 assert!(JsonLike::eq(vec![&left], vec![&right]));
638
639 assert!(!JsonLike::eq(vec![], vec![&right]));
640 assert!(!JsonLike::eq(vec![&right], vec![]));
641
642 assert!(JsonLike::eq(
643 vec![&left, &left1, &left2, &left3],
644 vec![&right, &right1, &right2, &right3]
645 ));
646
647 assert!(!JsonLike::eq(
648 vec![&left1, &left, &left2, &left3],
649 vec![&right, &right1, &right2, &right3]
650 ));
651 }
652
653 #[test]
654 fn less_value_test() {
655 let left = json!(10);
656 let right = json!(11);
657
658 assert!(JsonLike::less(vec![&left], vec![&right]));
659 assert!(!JsonLike::less(vec![&right], vec![&left]));
660
661 let left = json!(-10);
662 let right = json!(-11);
663
664 assert!(!JsonLike::less(vec![&left], vec![&right]));
665 assert!(JsonLike::less(vec![&right], vec![&left]));
666
667 let left = json!(-10.0);
668 let right = json!(-11.0);
669
670 assert!(!JsonLike::less(vec![&left], vec![&right]));
671 assert!(JsonLike::less(vec![&right], vec![&left]));
672
673 assert!(!JsonLike::less(vec![], vec![&right]));
674 assert!(!JsonLike::less(vec![&right, &right], vec![&left]));
675 }
676
677 #[test]
678 fn regex_test() {
679 let right = json!("[a-zA-Z]+[0-9]#[0-9]+");
680 let left1 = json!("a11#");
681 let left2 = json!("a1#1");
682 let left3 = json!("a#11");
683 let left4 = json!("#a11");
684
685 assert!(JsonLike::regex(
686 vec![&left1, &left2, &left3, &left4],
687 vec![&right]
688 ));
689 assert!(!JsonLike::regex(vec![&left1, &left3, &left4], vec![&right]))
690 }
691
692 #[test]
693 fn any_of_test() {
694 let right = json!([1, 2, 3, 4, 5, 6]);
695 let left = json!([1, 100, 101]);
696 assert!(JsonLike::any_of(vec![&left], vec![&right]));
697
698 let left = json!([11, 100, 101]);
699 assert!(!JsonLike::any_of(vec![&left], vec![&right]));
700
701 let left1 = json!(1);
702 let left2 = json!(11);
703 assert!(JsonLike::any_of(vec![&left1, &left2], vec![&right]));
704 }
705
706 #[test]
707 fn sub_set_of_test() {
708 let left1 = json!(1);
709 let left2 = json!(2);
710 let left3 = json!(3);
711 let left40 = json!(40);
712 let right = json!([1, 2, 3, 4, 5, 6]);
713 assert!(JsonLike::sub_set_of(
714 vec![&Value::Array(vec![
715 left1.clone(),
716 left2.clone(),
717 left3.clone()
718 ])],
719 vec![&right]
720 ));
721 assert!(!JsonLike::sub_set_of(
722 vec![&Value::Array(vec![left1, left2, left3, left40])],
723 vec![&right]
724 ));
725 }
726
727 #[test]
728 fn size_test() {
729 let left1 = json!("abc");
730 let left2 = json!([1, 2, 3]);
731 let left3 = json!([1, 2, 3, 4]);
732 let right = json!(3);
733 let right1 = json!(4);
734 assert!(JsonLike::size(vec![&left1], vec![&right]));
735 assert!(JsonLike::size(vec![&left2], vec![&right]));
736 assert!(!JsonLike::size(vec![&left3], vec![&right]));
737 assert!(JsonLike::size(vec![&left3], vec![&right1]));
738 }
739
740 #[test]
741 fn convert_paths() -> Result<(), JsonPathParserError> {
742 let r = convert_part(&JsonPath::Chain(vec![
743 path!($),
744 path!("abc"),
745 path!(idx!(1)),
746 ]))?;
747 assert_eq!(r, "/abc/1");
748
749 assert!(convert_part(&JsonPath::Chain(vec![path!($), path!(.."abc")])).is_err());
750
751 Ok(())
752 }
753
754 #[test]
755 fn test_references() -> Result<(), JsonPathParserError> {
756 let mut json = json!({
757 "a": {
758 "b": {
759 "c": 42
760 }
761 }
762 });
763
764 let path_str = convert_part(&JsonPath::Chain(vec![path!("a"), path!("b"), path!("c")]))?;
765
766 if let Some(v) = json.pointer_mut(&path_str) {
767 *v = json!(43);
768 }
769
770 assert_eq!(
771 json,
772 json!({
773 "a": {
774 "b": {
775 "c": 43
776 }
777 }
778 })
779 );
780
781 Ok(())
782 }
783 #[test]
784 fn test_js_reference() -> Result<(), JsonPathParserError> {
785 let mut json = json!({
786 "a": {
787 "b": {
788 "c": 42
789 }
790 }
791 });
792
793 let path = "$.a.b.c";
794
795 if let Some(v) = json.reference_mut(path)? {
796 *v = json!(43);
797 }
798
799 assert_eq!(
800 json,
801 json!({
802 "a": {
803 "b": {
804 "c": 43
805 }
806 }
807 })
808 );
809
810 Ok(())
811 }
812}