jsonpath_rust/path/
mod.rs

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
13/// The module is in charge of processing [[JsonPathIndex]] elements
14mod index;
15/// The module is responsible for processing of the [[JsonPath]] elements
16mod top;
17
18/// The `JsonLike` trait defines a set of methods and associated types for working with JSON-like data structures.
19///
20/// It provides a common interface for accessing and manipulating JSON data,
21/// allowing for operations such as
22///  - retrieving values by key,
23///  - iterating over elements
24/// -  performing various comparisons and transformations.
25///
26/// The trait is implemented for the `serde_json::Value` type already
27pub 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    /// Retrieves a reference to the value associated with the given key.
42    fn get(&self, key: &str) -> Option<&Self>;
43
44    /// Iterates over the elements with a given prefix and returns a vector of `JsonPathValue`.
45    fn itre(&self, pref: String) -> Vec<JsonPathValue<'_, Self>>;
46
47    /// Returns the length of the array as a `JsonPathValue`.
48    fn array_len(&self) -> JsonPathValue<'static, Self>;
49
50    /// Initializes an instance with a specific size.
51    fn init_with_usize(cnt: usize) -> Self;
52
53    /// Flattens nested structures and returns a vector of tuples containing references to the elements and their paths.
54    fn deep_flatten(&self, pref: String) -> Vec<(&Self, String)>;
55
56    /// Performs a deep search by key and returns a vector of tuples containing references to the elements and their paths.
57    fn deep_path_by_key<'a>(
58        &'a self,
59        key: ObjectField<'a, Self>,
60        pref: String,
61    ) -> Vec<(&'a Self, String)>;
62
63    /// Converts the element to an `Option<u64>`.
64    fn as_u64(&self) -> Option<u64>;
65
66    /// Checks if the element is an array.
67    fn is_array(&self) -> bool;
68
69    /// Converts the element to an `Option<&Vec<Self>>`.
70    fn as_array(&self) -> Option<&Vec<Self>>;
71
72    /// Compares the size of two vectors of references to elements.
73    fn size(left: Vec<&Self>, right: Vec<&Self>) -> bool;
74
75    /// Checks if the left vector is a subset of the right vector.
76    fn sub_set_of(left: Vec<&Self>, right: Vec<&Self>) -> bool;
77
78    /// Checks if any element in the left vector is present in the right vector.
79    fn any_of(left: Vec<&Self>, right: Vec<&Self>) -> bool;
80
81    /// Checks if the elements in the left vector match the regex pattern in the right vector.
82    fn regex(left: Vec<&Self>, right: Vec<&Self>) -> bool;
83
84    /// Checks if any element in the left vector is inside the right vector.
85    fn inside(left: Vec<&Self>, right: Vec<&Self>) -> bool;
86
87    /// Ensures the number on the left side is less than the number on the right side.
88    fn less(left: Vec<&Self>, right: Vec<&Self>) -> bool;
89
90    /// Compares elements for equality.
91    fn eq(left: Vec<&Self>, right: Vec<&Self>) -> bool;
92
93    /// Returns a null value.
94    fn null() -> Self;
95
96    /// Creates an array from a vector of elements.
97    fn array(data: Vec<Self>) -> Self;
98
99    /// Retrieves a reference to the element at the specified path.
100    /// The path is specified as a string and can be obtained from the query.
101    ///
102    /// # Arguments
103    /// * `path` -  A json path to the element specified as a string (root, field, index only).
104    fn reference<T>(&self, path: T) -> Result<Option<&Self>, JsonPathParserError>
105    where
106        T: Into<JsonPathStr>;
107
108    /// Retrieves a mutable reference to the element at the specified path.
109    ///
110    /// # Arguments
111    /// * `path` -  A json path to the element specified as a string (root, field, index only).
112    ///
113    /// # Examples
114    ///
115    /// ```
116    /// use serde_json::json;
117    /// use jsonpath_rust::{JsonPath, JsonPathParserError};
118    /// use jsonpath_rust::path::JsonLike;
119    ///
120    /// let mut json = json!([
121    ///     {"verb": "RUN","distance":[1]},
122    ///     {"verb": "TEST"},
123    ///     {"verb": "DO NOT RUN"}
124    /// ]);
125    ///
126    /// let path: Box<JsonPath> = Box::from(JsonPath::try_from("$.[?(@.verb == 'RUN')]").unwrap());
127    /// let elem = path
128    ///     .find_as_path(&json)
129    ///     .get(0)
130    ///     .cloned()
131    ///     .ok_or(JsonPathParserError::InvalidJsonPath("".to_string())).unwrap();
132    ///
133    /// if let Some(v) = json
134    ///     .reference_mut(elem).unwrap()
135    ///     .and_then(|v| v.as_object_mut())
136    ///     .and_then(|v| v.get_mut("distance"))
137    ///     .and_then(|v| v.as_array_mut())
138    /// {
139    ///     v.push(json!(2))
140    /// }
141    ///
142    /// assert_eq!(
143    ///     json,
144    ///     json!([
145    ///         {"verb": "RUN","distance":[1,2]},
146    ///         {"verb": "TEST"},
147    ///         {"verb": "DO NOT RUN"}
148    ///     ])
149    /// );
150    /// ```
151    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    /// ensure the number on the left side is less the number on the right side
392    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    /// compare elements
407    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
456/// The trait defining the behaviour of processing every separated element.
457/// type Data usually stands for json [[Value]]
458/// The trait also requires to have a root json to process.
459/// It needs in case if in the filter there will be a pointer to the absolute path
460pub trait Path<'a> {
461    type Data;
462    /// when every element needs to handle independently
463    fn find(&self, input: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
464        vec![input]
465    }
466    /// when the whole output needs to handle
467    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    /// defines when we need to invoke `find` or `flat_find`
475    fn needs_all(&self) -> bool {
476        false
477    }
478}
479
480/// all known Paths, mostly to avoid a dynamic Box and vtable for internal function
481pub 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
562/// The basic type for instances.
563pub(crate) type PathInstance<'a, T> = Box<dyn Path<'a, Data = T> + 'a>;
564
565/// The major method to process the top part of json part
566pub(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
598/// The method processes the operand inside the filter expressions
599fn 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}