json_walker/
json_walker.rs

1use crate::*;
2#[cfg(feature = "deserialize")]
3use crate::deserializer::deserialize_mod::Deserializer;
4pub use crate::Error;
5use crate::parser_core::{extract_current_value, get_stack_top_index, Parser, walk_forward, get_current_level, get_path, get_recent_piece, seek_by_level_offset};
6pub use crate::parser_core::{Content, Item, Parser as JsonWalker, PathItem, TextItem, ValueType};
7pub use crate::readers::*;
8
9impl Parser {
10    /// return the level of current position in json string.
11    /// for more information check out next_item_by_level() doc
12    pub fn get_current_level(&mut self) -> f32 {
13        get_current_level(self)
14    }
15
16    /// json has tree structure. this function returns that path to the current position with some details
17    pub fn get_path(&mut self) -> Vec<PathItem> {
18        get_path(self)
19    }
20
21    /// if mem_size is set in new() function, this function will return the latest piece of json, so you can apply a regex operation for example
22    pub fn get_recent_piece(&mut self) -> String {
23        get_recent_piece(self)
24    }
25
26    /// Parse json until the position at which, node level reaches the target_level_offset
27    /// ## Sample json with level in different positions after parsing each element:
28    /// <pre>
29    /// <span style="color:red">
30    /// 0 1       1 1.5   1  1       1 1.5 2     2  2  3        3 3.5   3  2  1  0
31    /// </span>
32    /// <span style="color:yellow">
33    /// ↓ ↓       ↓  ↓    ↓  ↓       ↓  ↓  ↓     ↓  ↓  ↓        ↓  ↓    ↓  ↓  ↓  ↓
34    /// </span>
35    ///  {  "key1"  :  123  ,  "key2"  :  [  true  ,  {  "key21"  :  2.5  }  ]  }
36    /// </pre>
37    ///
38    /// The result determines if there can be more data or not.
39    /// For example if cursor is the above json is after 2.5 and before "}", result will be false. It means that there is no more data for level 3.
40    pub fn seek_by_level_offset(&mut self, target_level_offset: f32) -> bool {
41        seek_by_level_offset(self, target_level_offset)
42    }
43
44    /// Return current path string.
45    /// - default root is "#"
46    /// - objects are surrounded between "{" and "}"
47    /// - arrays are surrounded between "[" and "]"
48    /// - each item is formatted like (latest_key_name, index_of_child_in_its_parent)
49    /// #### Consider below json with detailed path for different positions. The **Green** ones are the positions which you can access via **next_item()** function.
50    /// <pre>
51    /// { "key1" : 1 , ..., "key8" : [ "value1" , ..., "value6" , { "key81" : ... } ]}
52    ///  ⎟      ⎟ ⎟ ⎟      ⎟      ⎟ ⎟ ⎟        ⎟ ⎟    ⎟        ⎟           ⎟       ↓
53    ///  ⎟      ⎟ ⎟ ⎟      ⎟      ⎟ ⎟ ⎟        ⎟ ⎟    ⎟        ⎟           ↓       #/{key8,7}/[key8,6]/
54    ///  ⎟      ⎟ ⎟ ⎟      ⎟      ⎟ ⎟ ⎟        ⎟ ⎟    ⎟        ↓           <span style="color:green">#/{key8,7}/[key8,6]/{key81,0}/</span>
55    ///  ⎟      ⎟ ⎟ ⎟      ⎟      ⎟ ⎟ ⎟        ⎟ ⎟    ↓        <span style="color:green">#/{key8,7}/[key8,6]/</span>
56    ///  ⎟      ⎟ ⎟ ⎟      ⎟      ⎟ ⎟ ⎟        ⎟ ↓    #/{key8,7}/[key8,5]/
57    ///  ⎟      ⎟ ⎟ ⎟      ⎟      ⎟ ⎟ ⎟        ↓ #/{key8,7}/[key8,1]/
58    ///  ⎟      ⎟ ⎟ ⎟      ⎟      ⎟ ⎟ ↓        <span style="color:green">#/{key8,7}/[key8,0]/</span>
59    ///  ⎟      ⎟ ⎟ ⎟      ⎟      ⎟ ↓ #/{key8,7}/[key8,0]/
60    ///  ⎟      ⎟ ⎟ ⎟      ⎟      ↓ #/{key8,7}/
61    ///  ⎟      ⎟ ⎟ ⎟      ↓      <span style="color:green">#/{key8,7}/</span>
62    ///  ⎟      ⎟ ⎟ ↓      #/{key7,7}/
63    ///  ⎟      ⎟ ↓ <span style="color:green">#/{key1,0}/</span>
64    ///  ⎟      ↓ #/{key1,0}/
65    ///  ↓      <span style="color:green">#/{key1,0}/</span>
66    ///  #/{#,0}/
67    /// </pre>
68    pub fn get_path_string(&mut self) -> String {
69        let p = self.get_path();
70        let mut s = String::with_capacity(p.len() * 10);
71        for x in p.iter() {
72            s.push_str(&x.to_string());
73            s.push('/');
74        }
75        s
76    }
77
78    /// Return next key or value in json. No matter if the item belongs to the child node or parent. If  no item exists, None will be returned
79    pub fn next_item(&mut self) -> Result<Item, Error> {
80        while self.next_byte != NIL {
81            match walk_forward(self) {
82                TextItem::Key(t) | TextItem::Value(t) => {
83                    return Ok(t);
84                }
85                _ => {
86                    continue;
87                }
88            }
89        }
90        Err(Error::new_eos())
91    }
92
93    /// Next key will be returned and values will be ignored. No matter if it belongs to child or parent node. If there is no more key, None would be the result
94    pub fn next_key(&mut self) -> Result<Item, Error> {
95        while self.next_byte != NIL {
96            match walk_forward(self) {
97                TextItem::Key(t) => {
98                    return Ok(t);
99                }
100                _ => {
101                    continue;
102                }
103            }
104        }
105        Err(Error::new_eos())
106    }
107
108    /// The json will be parsed till the mentioned key. If key does not exist or it is already passed,
109    /// parsing will continue to the end of stream.
110    pub fn next_key_by_name(&mut self, name: &str) -> Result<Item, Error> {
111        let mut key;
112        loop {
113            key = self.next_key();
114            match key {
115                Ok(t) if !t.1.eq(name) => {
116                    continue;
117                }
118                _ => {}
119            }
120            break;
121        }
122        key
123    }
124
125    /// The json will be parsed till the next sibling key.
126    /// At the end of current element (object or array), None will be returned and cursor will not move any further by this function
127    pub fn next_sibling_key(&mut self) -> Result<Item, Error> {
128        if self.next_byte != NIL {
129            let top_index = get_stack_top_index(self);
130            let top_stack_level = self.stack[top_index].level;
131            let diff = top_stack_level - top_stack_level.floor();
132            if seek_by_level_offset(self, diff) {
133                return self.next_key();
134            }
135        }
136        Err(Error::new_eos())
137    }
138
139    /// Return next child key.
140    /// The key must be only one level lower than the current node, so grand children will not count in.
141    pub fn next_child_key(&mut self) -> Result<Item, Error> {
142        if self.next_byte != NIL {
143            let top_index = get_stack_top_index(self);
144            let top_stack_level = self.stack[top_index].level;
145            let diff = (top_stack_level + 1.0).floor() - top_stack_level;
146            if seek_by_level_offset(self, diff) {
147                return self.next_key();
148            }
149        }
150        Err(Error::new_eos())
151    }
152
153    /// Return next key of parent (1 level up) or None if parent has no more key
154    pub fn next_key_from_parent(&mut self) -> Result<Item, Error> {
155        if self.next_byte != NIL {
156            let top_index = get_stack_top_index(self);
157            let top_stack_level = self.stack[top_index].level;
158            let diff = (top_stack_level - 1.0).ceil() - top_stack_level;
159            if seek_by_level_offset(self, diff) {
160                return self.next_key();
161            }
162        }
163        Err(Error::new_eos())
164    }
165
166    /// Parse json until the position in which, node level reaches the target_level.
167    /// - For short, consider each "[" and "{" one level increase and "]" and "}" one level decrease
168    /// - ":" is used for accessing simple values
169    /// ## Sample json with node level in different positions:
170    /// <pre>
171    /// 0 1       1.5   1      1.5 2     2 3        3.5    2 1 0
172    /// <span style="color:yellow">
173    /// ↓ ↓        ↓    ↓        ↓ ↓     ↓ ↓         ↓     ↓ ↓ ↓
174    /// </span>
175    ///  { "key1" : 123, "key2" : [ true, { "key21" : 2.5 } ] }
176    /// </pre>
177    pub fn next_item_by_level(&mut self, target_level: f32) -> Result<Item, Error> {
178        let mut ti;
179        let mut stack_top;
180        while self.next_byte != NIL {
181            ti = walk_forward(self);
182            stack_top = self.stack.last().unwrap();
183            if stack_top.level == target_level {
184                match ti {
185                    TextItem::Key(t) | TextItem::Value(t) => {
186                        return Ok(t);
187                    }
188                    _ => {
189                        continue;
190                    }
191                }
192            }
193        }
194        Err(Error::new_eos())
195    }
196
197    /// To jump to the desired item (key or value), use this function.
198    /// This function executes the provided patterns from last to first on any found key or value.
199    /// When ever a pattern fails, it doesn't check the others and scans for another item in json,
200    /// so it is recommended to minimize number of patterns to reach higher performance.
201    /// - This function works by path, so please check out docs of get_path_string() and next_item_by_level() functions.
202    /// - Notice that pattern is not something like **regex**. If you need **regex** to find the item, you can use get_recent_piece() function.
203    ///
204    /// # Example
205    ///```
206    /// fn main(){
207    ///    use json_walker::json_walker::{CurrentState, Item, JsonWalker, StringReader, ValueType};
208    ///
209    ///    let json = r#"[{"key1":{"key4":100},"key2":10},[{"key1":{"key4":300}, "key3":100}],"key1"]"#;
210    ///    let mut walker = JsonWalker::new(StringReader::new(json.to_string()), 50);
211    ///    let patterns = vec![
212    ///       |cs: &CurrentState| -> bool{ cs.level == 2.0 && cs.nth_occurrence == 0 },
213    ///       |cs: &CurrentState| -> bool{ cs.latest_key.eq("key1") && cs.level == 3.0 },
214    ///       |cs: &CurrentState| -> bool{cs.latest_key.eq("key4") },
215    ///    ];
216    ///
217    ///    let item = walker.next_item_by_pattern(&patterns);
218    ///    assert_eq!(item, Ok((ValueType::Str, String::from("key4"))));
219    /// }
220    /// ```
221    /// In the above example 3 patterns are hired p0, p1 & p2 and we want to find the second key4.
222    ///
223    /// In marked positions, the provided patterns get called from last to first:
224    /// <pre>
225    /// [{"key1" :{"key4" :100 },"key2" :10 },[{"key1" :{"key4" :300}, "key3":100}],"key1"]
226    /// <span style="color:red">
227    ///        1        2    3        4   5          6        7
228    /// </span>
229    ///</pre>
230    ///
231    /// | pos | path | pattern|
232    /// |-----|---------------------------------------|----------|
233    /// |   | _ | p0: level == 2.0 && nth_occurrence == 0
234    /// | 1 | _ | p1: latest_key.eq("key1") && level == 3.0
235    /// |   | #/[#, 0]/<span style="color:teal">{key1, 0}</span>/ | p2: **latest_key.eq("key4")** 🔴 ↩️ <span style="color:red">->(key is "key1")</span>
236    /// |-----|---------------------------------------|-----------------------------/---------------------|
237    /// |   | _ | p0:  level == 2.0 && nth_occurrence == 0
238    /// | 2 | #/[#, 0]/<span style="color:teal">{key1, 0}</span>/{key4, 0}/ | p1: latest_key.eq("key1") && **level == 3.0** 🔴 ↩️ <span style="color:red">->(level of key1 is "2")</span>
239    /// |   | #/[#, 0]/{key1, 0}/<span style="color:teal">{key4, 0}</span>/ | p2: latest_key.eq("key4") 🟢
240    /// |-----|---------------------------------------|--------------------------------------------------|
241    /// |   | _ | p0:  level == 2.0 && nth_occurrence == 0
242    /// | 3 | #/[#, 0]/<span style="color:teal">{key1, 0}</span>/{key4, 0}/ | p1: latest_key.eq("key1") && **level == 3.0** 🔴 ↩️ <span style="color:red">->(level of key1 is "2")</span>
243    /// |   | #/[#, 0]/{key1, 0}/<span style="color:teal">{key4, 0}</span>/ | p2: latest_key.eq("key4") 🟢
244    /// |-----|---------------------------------------|--------------------------------------------------|
245    /// |   | _ | p0:  level == 2.0 && nth_occurrence == 0
246    /// | 4 | _ | p1: latest_key.eq("key1") && level == 3.0
247    /// |   | #/[#, 0]/<span style="color:teal">{key2, 1}</span>/ | p2: **latest_key.eq("key4")** 🔴 ↩️ <span style="color:red">->(key is "key2")</span>
248    /// |-----|---------------------------------------|--------------------------------------------------|
249    /// |   | _ | p0:  level == 2.0 && nth_occurrence == 0
250    /// | 5 | _ | p1: latest_key.eq("key1") && level == 3.0
251    /// |   | #/[#, 0]/<span style="color:teal">{key2, 1}</span>/ | p2: **latest_key.eq("key4")** 🔴 ↩️ <span style="color:red">->(key is "key2")</span>
252    /// |-----|---------------------------------------|--------------------------------------------------|
253    /// |   | _ | p0:  level == 2.0 && nth_occurrence == 0
254    /// | 6 | _ | p1: latest_key.eq("key1") && level == 3.0
255    /// |   | #/[#, 1]/<span style="color:teal">{key1, 0}</span>/ | p2: **latest_key.eq("key4")** 🔴 ↩️ <span style="color:red">->(key is "key1")</span>
256    /// |-----|---------------------------------------|--------------------------------------------------|
257    /// |   | #/[#, 1]/<span style="color:teal">[#, 0]</span>/{key1, 0}/{key4, 0}/ | p0:  level == 2.0 && nth_occurrence == 0 🟢
258    /// | 7 | #/[#, 1]/[#, 0]/<span style="color:teal">{key1, 0}</span>/{key4, 0}/ | p1: latest_key.eq("key1") && level == 3.0 🟢
259    /// |   | #/[#, 1]/[#, 0]/{key1, 0}/<span style="color:teal">{key4, 0}</span>/ | p2: latest_key.eq("key4") 🟢
260    pub fn next_item_by_pattern(&mut self, pattern: &Vec<impl Fn(&CurrentState) -> bool>) -> Result<Item, Error> {
261        let pat_top = pattern.len() - 1;
262        let mut pat_index;
263        let mut stack_item;
264
265        let mut is_key;
266        let mut item;
267        'next_item: while self.next_byte != NIL {
268            match walk_forward(self) {
269                TextItem::Key(m) => {
270                    item = m;
271                    is_key = true;
272                }
273                TextItem::Value(m) => {
274                    item = m;
275                    is_key = false;
276                }
277                _ => {
278                    continue;
279                }
280            }
281            pat_index = pat_top;
282            for si in (1..=self.stack.len() - 1).rev() {
283                stack_item = &self.stack[si];
284                if stack_item.symbol != ':' {
285                    if !pattern[pat_index](&CurrentState {
286                        latest_key: &stack_item.key,
287                        nth_occurrence: stack_item.nth,
288                        level: stack_item.level,
289                        current_item: &item,
290                        is_key,
291                    }) {
292                        continue 'next_item;
293                    }
294                    if pat_index == 0 {
295                        return Ok(item);
296                    }
297                    pat_index -= 1;
298                }
299            }
300        }
301        Err(Error::new_eos())
302    }
303
304    fn walk_before_value(&mut self) {
305        while self.next_byte == b':' || self.next_byte == b',' || self.stack.last().is_some_and(|s| s.symbol == '{') {
306            walk_forward(self);
307        }
308    }
309
310    /// Based on cursor location, the value of current key will be returned.
311    /// Value can be a single string, integer, float, boolean, null, object or array.
312    /// If there is no progress, the whole object will be returned
313    pub fn current_value_content(&mut self) -> Result<Content, Error> {
314        self.walk_before_value();
315        if self.next_byte != NIL {
316            let top_index = get_stack_top_index(self);
317            return Ok(extract_current_value(self, top_index));
318        }
319        Err(Error::new_eos())
320    }
321
322    /// Based on cursor location, the value of current key will be deserialize.
323    #[cfg(feature = "deserialize")]
324    pub fn current_value<V>(&mut self) -> Result<V, Error> where V: for<'a> serde::de::Deserialize<'a>, {
325        self.walk_before_value();
326        if self.next_byte != NIL {
327            let mut de = Deserializer::new(self);
328            return V::deserialize(&mut de);
329        }
330        Err(Error::new_eos())
331    }
332
333    /// move n item including key, value or other none white space char such as "{", "[", "}", "]", ":" or ","
334    pub fn move_n_element_forward(&mut self, n: usize) {
335        for _ in 0..n {
336            walk_forward(self);
337        }
338    }
339}
340
341pub struct CurrentState<'a> {
342    /// **latest_key** is the latest key seen in the current position
343    pub latest_key: &'a str,
344
345    /// **nth_occurrence** is the index of the current item (key or value) in json
346    pub nth_occurrence: usize,
347
348    /// **level: f32** is the level of the current position. Please check out next_item_by_level() docs
349    pub level: f32,
350
351    /// **current_item** is the current scanned which is Item(ValueType, value as string)
352    pub current_item: &'a Item,
353
354    /// **is_key: bool**, determines if the current item is a key or value
355    pub is_key: bool,
356}
357
358#[cfg(test)]
359mod walker_tests {
360    use std::collections::BTreeMap;
361
362    use crate::Error;
363    use crate::json_walker::{CurrentState, JsonWalker};
364    use crate::parser_core::{Content, ValueType};
365    use crate::readers::StringReader;
366
367    const CORRECT_JSON: &str = r#" {"key1":null,"key2":true,"key3":false,"key4":111,"key5":111.111,"key6":"str1 \":{}[],","key7":{  "key71" : null ,  "key72" : true ,  "key73" : false ,  "key74" : 222 ,  "key75" : 222.222 ,  "key76" : "str2 \":{}[]," ,  "key78" : [    null ,    true ,    false ,    333 ,    333.333 ,    "str3 \":{}[]," ,    {  } ,    [  ]  ] ,  "key79" : {} ,  "key710": [  ] } , "key8" : [  null ,  true ,  false ,  444 ,  444.444 ,  "str4 \":{}[]," ,  {    "key81" : null ,    "key82" : true ,    "key83" : false ,    "key84" : 555 ,
368      "key85" : 555.555 ,
369      "key86" : "str5 \":{}[]," ,    "key89" : {} ,    "key810" : [ ]  } ,  { } ,  [ ]  ] , "key9" : { } , "key10" : [ ]
370} "#;
371
372    #[test]
373    fn test_next_item() {
374        // keys and values must be retrieved in order
375        let words = [
376            "key1",
377            "null",
378            "key2",
379            "true",
380            "key3",
381            "false",
382            "key4",
383            "111",
384            "key5",
385            "111.111",
386            "key6",
387            "str1 \":{}[],",
388            "key7",
389            "key71",
390            "null",
391            "key72",
392            "true",
393            "key73",
394            "false",
395            "key74",
396            "222",
397            "key75",
398            "222.222",
399            "key76",
400            "str2 \":{}[],",
401            "key78",
402            "null",
403            "true",
404            "false",
405            "333",
406            "333.333",
407            "str3 \":{}[],",
408            "key79",
409            "key710",
410            "key8",
411            "null",
412            "true",
413            "false",
414            "444",
415            "444.444",
416            "str4 \":{}[],",
417            "key81",
418            "null",
419            "key82",
420            "true",
421            "key83",
422            "false",
423            "key84",
424            "555",
425            "key85",
426            "555.555",
427            "key86",
428            "str5 \":{}[],",
429            "key89",
430            "key810",
431            "key9",
432            "key10",
433        ];
434        let mut word_index = 0;
435        let mut walker = JsonWalker::new(StringReader::new(CORRECT_JSON.to_string()), 50);
436        loop {
437            match walker.next_item() {
438                Err(_) => {
439                    break;
440                }
441                Ok(t) => {
442                    assert!(t.1.eq(words[word_index]));
443                    word_index += 1;
444                }
445            }
446        }
447    }
448
449    #[test]
450    fn test_next_key() {
451        // only keys must be retrieved in order, no matter if the key belongs to a child or parent node
452        let words = [
453            "key1", "key2", "key3", "key4", "key5", "key6", "key7", "key71", "key72", "key73",
454            "key74", "key75", "key76", "key78", "key79", "key710", "key8", "key81", "key82",
455            "key83", "key84", "key85", "key86", "key89", "key810", "key9", "key10",
456        ];
457        let mut word_index = 0;
458        let mut walker = JsonWalker::new(StringReader::new(CORRECT_JSON.to_string()), 50);
459        loop {
460            match walker.next_key() {
461                Err(_) => {
462                    break;
463                }
464                Ok(t) => {
465                    assert!(t.1.eq(words[word_index]));
466                    word_index += 1;
467                }
468            }
469        }
470    }
471
472    #[test]
473    fn test_next_key_by_name() {
474        // key must be retrieved by its name, no matter if the key belongs to a child or parent node
475        let mut walker = JsonWalker::new(StringReader::new(CORRECT_JSON.to_string()), 50);
476        let result = walker.next_key_by_name("key2");
477        assert_eq!(
478            Ok((ValueType::Str, String::from("key2"))),
479            result,
480            r#"next_key_by_name("key2") != "key2" "#
481        );
482
483        let result = walker.next_key_by_name("key71");
484        assert_eq!(
485            Ok((ValueType::Str, String::from("key71"))),
486            result,
487            r#"next_key_by_name("key71") != "key71" "#
488        );
489
490        let result = walker.next_key_by_name("key82");
491        assert_eq!(
492            Ok((ValueType::Str, String::from("key82"))),
493            result,
494            r#"next_key_by_name("key82") != "key82" "#
495        );
496
497        let result = walker.next_key_by_name("key");
498        assert_eq!(Err(Error::new_eos()), result, r#"next_key_by_name("key") != "key" "#);
499    }
500
501    #[test]
502    fn test_get_path_and_get_path_string() {
503        let mut walker = JsonWalker::new(StringReader::new(CORRECT_JSON.to_string()), 50);
504        let _ = walker.next_key_by_name("key81");
505        let path = walker.get_path_string();
506        assert_eq!(path, "#/{key8,7}/[key8,6]/{key81,0}/");
507    }
508
509    #[test]
510    fn test_next_sibling_key_for_level0() {
511        let mut walker = JsonWalker::new(StringReader::new(CORRECT_JSON.to_string()), 50);
512        let _ = walker.next_key();
513        let keys = [
514            "key1", "key2", "key3", "key4", "key5", "key6", "key7", "key8", "key9", "key10",
515        ];
516        let mut i = 1;
517        loop {
518            match walker.next_sibling_key() {
519                Err(_) => {
520                    assert_eq!(i, keys.len());
521                    break;
522                }
523                Ok(k) => {
524                    assert_eq!(k.1, String::from(keys[i]));
525                    i += 1;
526                }
527            }
528        }
529    }
530
531    #[test]
532    fn test_next_sibling_key_for_level1() {
533        let mut walker = JsonWalker::new(StringReader::new(CORRECT_JSON.to_string()), 50);
534        let _ = walker.next_key_by_name("key71");
535        let keys = [
536            "key71", "key72", "key73", "key74", "key75", "key76", "key78", "key79", "key710",
537        ];
538        let mut i = 1;
539        loop {
540            match walker.next_sibling_key() {
541                Err(_) => {
542                    assert_eq!(i, keys.len());
543                    break;
544                }
545                Ok(k) => {
546                    assert_eq!(k.1, String::from(keys[i]));
547                    i += 1;
548                }
549            }
550        }
551    }
552
553    #[test]
554    fn test_next_sibling_key_for_level2() {
555        let mut walker = JsonWalker::new(StringReader::new(CORRECT_JSON.to_string()), 50);
556        let _ = walker.next_key_by_name("key81");
557        let keys = [
558            "key81", "key82", "key83", "key84", "key85", "key86", "key89", "key810",
559        ];
560        let mut i = 1;
561        loop {
562            match walker.next_sibling_key() {
563                Err(_) => {
564                    assert_eq!(i, keys.len());
565                    break;
566                }
567                Ok(k) => {
568                    assert_eq!(k.1, String::from(keys[i]));
569                    i += 1;
570                }
571            }
572        }
573    }
574
575    #[test]
576    fn test_next_child_key() {
577        let mut walker = JsonWalker::new(StringReader::new(CORRECT_JSON.to_string()), 50);
578        let _ = walker.next_key_by_name("key1");// seek key1
579        let item = walker.next_child_key();
580        assert_eq!(item, Ok((ValueType::Str, "key71".to_string())))
581    }
582
583    #[test]
584    fn test_next_key_from_parent() {
585        let mut walker = JsonWalker::new(StringReader::new(CORRECT_JSON.to_string()), 50);
586        let _ = walker.next_key_by_name("key71");// seek key1
587        let item = walker.next_key_from_parent();
588        assert_eq!(item, Ok((ValueType::Str, "key8".to_string())))
589    }
590
591    #[test]
592    fn test_next_item_by_pattern_some_items_in_middle() {
593        let json = r#"[{"key1":"key1","key2":10},[{"key1":null, "key3":100}],"key1"]"#;
594        let mut walker = JsonWalker::new(StringReader::new(json.to_string()), 50);
595        let pattern = vec![|cs: &CurrentState| -> bool { cs.current_item.1.eq("key1") }];
596
597        for _ in 0..4 {
598            let item = walker.next_item_by_pattern(&pattern);
599            assert_eq!(item, Ok((ValueType::Str, String::from("key1"))));
600        }
601
602        let item = walker.next_item_by_pattern(&pattern);
603        assert_eq!(item, Err(Error::new_eos()));
604    }
605
606    #[test]
607    fn test_next_item_by_pattern_item_in_path() {
608        let json = r#"[{"key1":{"key4":100},"key2":10},[{"key1":{"key4":300}, "key3":100}],"key1"]"#;
609        let mut walker = JsonWalker::new(StringReader::new(json.to_string()), 50);
610        let pattern = vec![
611            |cs: &CurrentState| -> bool { cs.level == 2.0 && cs.nth_occurrence == 0 },
612            |cs: &CurrentState| -> bool { cs.latest_key.eq("key1") && cs.level == 3.0 },
613            |cs: &CurrentState| -> bool { cs.latest_key.eq("key4") },
614        ];
615
616        let item = walker.next_item_by_pattern(&pattern);
617        assert_eq!(item, Ok((ValueType::Str, String::from("key4"))));
618    }
619
620    #[test]
621    fn test_next_item_by_level() {
622        let json = r#"[{"key1":{"key4":100},"key2":10},[{"key1":{"key4":300}, "key3":100}],"key1"]"#;
623        let mut walker = JsonWalker::new(StringReader::new(json.to_string()), 50);
624        let item = walker.next_item_by_level(2.0);
625        assert_eq!(item, Ok((ValueType::Str, String::from("key1"))));
626
627        let item = walker.next_item_by_level(4.0);
628        assert_eq!(item, Ok((ValueType::Str, String::from("key4"))));
629    }
630
631    #[test]
632    fn test_current_value() {
633        let item = |v: &str, is_str: bool| -> Content {
634            Content::Simple((
635                if is_str {
636                    ValueType::Str
637                } else {
638                    ValueType::Int
639                },
640                String::from(v),
641            ))
642        };
643
644        let object = |d: Vec<(&str, Content)>| -> Content {
645            let mut o = BTreeMap::new();
646            for x in d {
647                o.insert(String::from(x.0), x.1);
648            }
649            Content::Object(o)
650        };
651
652        let array = |d: Vec<Content>| -> Content { Content::Array(d) };
653
654        let s = r#"[{"key1" :{"key4" :100 },"key2" :10 },[{"key1" :{"key4" :300}, "key3":100}],"key1"]"#;
655
656        // fetch all
657        let mut walker = JsonWalker::new(StringReader::new(s.to_string()), 50);
658        let a = walker.current_value_content();
659        assert_eq!(
660            a,
661            Ok(array(vec![
662                object(vec![
663                    ("key1", object(vec![("key4", item("100", false))])),
664                    ("key2", item("10", false)),
665                ]),
666                array(vec![object(vec![
667                    ("key1", object(vec![("key4", item("300", false))])),
668                    ("key3", item("100", false)),
669                ])]),
670                item("key1", true),
671            ]))
672        );
673
674        // fetch only first item
675        let mut walker = JsonWalker::new(StringReader::new(s.to_string()), 50);
676        walker.move_n_element_forward(1);
677        let a = walker.current_value_content();
678        assert_eq!(
679            a,
680            Ok(object(vec![
681                ("key1", object(vec![("key4", item("100", false))])),
682                ("key2", item("10", false)),
683            ]))
684        );
685
686        // fetch only a simple item
687        let mut walker = JsonWalker::new(StringReader::new(s.to_string()), 50);
688        let _ = walker.next_key_by_name("key2");
689        let a = walker.current_value_content();
690        assert_eq!(a, Ok(item("10", false)));
691    }
692
693    #[test]
694    fn test_json_file() {}
695}
696
697#[cfg(test)]
698#[cfg(feature = "deserialize")]
699mod walker_test_de {
700    use crate::json_walker::JsonWalker;
701    use crate::json_walker::walker_test_de::data1::MixedDataTypes;
702    use crate::json_walker::walker_test_de::data2::Person;
703    use crate::readers::StringReader;
704
705    mod data1 {
706        use serde::{Deserialize, Serialize};
707
708        pub fn create_data() -> MixedDataTypes {
709            MixedDataTypes {
710                null: None,
711                unsigned: Some(1),
712                int: [2, -2],
713                float1: [3.3, -3.3],
714                character: 'g',
715                boolean: false,
716                string: "Hello".into(),
717                bytes: vec![4, b'h'],
718                tuple: (5, 6.7, 'b', None, vec![8], Color::Red, Point { x: 10, y: -10 }),
719                array1: vec![('l', "world".into()), ('x', "oops".into())],
720                array2: vec![Point { x: 11, y: -11 }, Point { x: 12, y: -12 }],
721                array3: vec![Color::Green, Color::Blue],
722                enum1: Message::Quit,
723                enum2: Message::Move { x: 13, y: -13 },
724                enum3: Message::Write("This is a test".into()),
725                enum4: Message::ChangeColor(Color::Green, Point { x: 14, y: -14 }),
726            }
727        }
728
729        #[derive(Serialize, Deserialize, Debug, PartialEq)]
730        pub struct MixedDataTypes {
731            pub null: Option<usize>,
732            pub unsigned: Option<usize>,
733            pub int: [i32; 2],
734            pub float1: [f32; 2],
735            pub character: char,
736            pub boolean: bool,
737            pub string: String,
738            pub bytes: Vec<u8>,
739            pub tuple: (i32, f32, char, Option<String>, Vec<i32>, Color, Point),
740            pub array1: Vec<(char, String)>,
741            pub array2: Vec<Point>,
742            pub array3: Vec<Color>,
743            pub enum1: Message,
744            pub enum2: Message,
745            pub enum3: Message,
746            pub enum4: Message,
747        }
748
749        #[derive(Serialize, Deserialize, Debug, PartialEq)]
750        pub enum Message {
751            Quit,
752            Move { x: i32, y: i32 },
753            Write(String),
754            ChangeColor(Color, Point),
755        }
756
757        #[derive(Serialize, Deserialize, Debug, PartialEq)]
758        pub enum Color {
759            Red,
760            Green,
761            Blue,
762        }
763
764        #[derive(Serialize, Deserialize, Debug, PartialEq)]
765        pub struct Point {
766            pub x: i32,
767            pub y: i32,
768        }
769    }
770
771    mod data2 {
772        use serde::{Deserialize, Serialize};
773
774        pub fn create_data() -> Vec<Person> {
775            vec![
776                Person {
777                    name: "John Doe".to_string(),
778                    age: -30,
779                    unsigned_age: 25,
780                    address: Address {
781                        street: "123 Main St".to_string(),
782                        city: "New York".to_string(),
783                        country: "USA".to_string(),
784                    },
785                    hobbies: vec!["reading", "painting", "hiking"].iter().map(|s| s.to_string()).collect(),
786                    favorite_color: Color::Blue,
787                    height: 1.75,
788                    weight: -65.5,
789                    friends: Some(vec![
790                        (Friend { name: "Alice".to_string(), age: -28 }, true, Address {
791                            street: "oh fuck".to_string(),
792                            city: "Laas".to_string(),
793                            country: "USA".to_string(),
794                        },
795                         vec!["0123456".to_string()]
796                        ),
797                        (Friend { name: "Bob".to_string(), age: -32 }, false, Address {
798                            street: "shit".to_string(),
799                            city: "goh".to_string(),
800                            country: "USA".to_string(),
801                        },
802                         vec!["0123459846".to_string(), "54654032".to_string()]),
803                    ]),
804                    is_iranian: false,
805                },
806                Person {
807                    name: "Arash".to_string(),
808                    age: 36,
809                    unsigned_age: 10,
810                    address: Address {
811                        street: "123 Main St".to_string(),
812                        city: "Hamedan-Hamedan".to_string(),
813                        country: "Iran".to_string(),
814                    },
815                    hobbies: vec!["gaming", "mount climbing", "bicycle"].iter().map(|s| s.to_string()).collect(),
816                    favorite_color: Color::Green,
817                    height: 164.1,
818                    weight: -82.3,
819                    friends: None,
820                    is_iranian: true,
821                },
822            ]
823        }
824
825        #[derive(Debug, Serialize, Deserialize, PartialEq)]
826        pub enum Color {
827            Red,
828            Green,
829            Blue,
830        }
831
832        #[derive(Debug, Serialize, Deserialize, PartialEq)]
833        pub struct Person {
834            name: String,
835            age: i32,
836            unsigned_age: u32,
837            address: Address,
838            hobbies: Vec<String>,
839            favorite_color: Color,
840            height: f64,
841            weight: f64,
842            // Option<Vec<(Friend, is_close, Address, Vec<phones>)>>
843            friends: Option<Vec<(Friend, bool, Address, Vec<String>)>>,
844            is_iranian: bool,
845
846        }
847
848        #[derive(Debug, Serialize, Deserialize, PartialEq)]
849        pub struct Address {
850            street: String,
851            city: String,
852            country: String,
853        }
854
855        #[derive(Debug, Serialize, Deserialize, PartialEq)]
856        pub struct Friend {
857            name: String,
858            age: i32,
859        }
860    }
861
862    #[test]
863    fn test_data1_de() {
864        let data = data1::create_data();
865        let json = serde_json::to_string(&data).unwrap();
866        let mut walker = JsonWalker::new(StringReader::new(json), 50);
867        let de = walker.current_value::<MixedDataTypes>().unwrap();
868        assert_eq!(de, data);
869    }
870
871    #[test]
872    fn test_data2_de() {
873        let data = data2::create_data();
874        let json = serde_json::to_string(&data).unwrap();
875        let mut walker = JsonWalker::new(StringReader::new(json), 50);
876        let de = walker.current_value::<Vec<Person>>().unwrap();
877        assert_eq!(de, data);
878    }
879}