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 pub fn get_current_level(&mut self) -> f32 {
13 get_current_level(self)
14 }
15
16 pub fn get_path(&mut self) -> Vec<PathItem> {
18 get_path(self)
19 }
20
21 pub fn get_recent_piece(&mut self) -> String {
23 get_recent_piece(self)
24 }
25
26 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 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 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 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 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 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 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 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 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 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 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 #[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 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 pub latest_key: &'a str,
344
345 pub nth_occurrence: usize,
347
348 pub level: f32,
350
351 pub current_item: &'a Item,
353
354 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 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 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 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");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");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 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 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 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 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}