json_flat_parser/
serializer.rs

1use std::cmp::Ordering;
2use std::fmt::Debug;
3
4use std::str::FromStr;
5use crate::{FlatJsonValue, GetBytes, ValueType};
6
7#[cfg(feature = "indexmap")]
8type Map<K, V> = indexmap::IndexMap<K, V>;
9#[cfg(not(feature = "indexmap"))]
10type Map<K, V> = std::collections::HashMap<K, V>;
11
12#[derive(Debug)]
13pub enum Value<V> {
14    Object(Map<String, Value<V>>),
15    ObjectSerialized(V),
16    Array(Vec<Value<V>>),
17    ArraySerialized(V),
18    Number(f64),
19    Integer(i64),
20    String(V),
21    Bool(bool),
22    Null,
23}
24
25#[macro_export]
26macro_rules! vec_matches {
27    () => {false};
28    ($v1:expr, $v2:expr) => {
29        if $v1.len() != $v2.len() {
30            false
31        } else {
32            let mut matches = true;
33            for i in 0..$v1.len() {
34                if !$v1[i].eq(&$v2[i]) {
35                    matches = false;
36                    break;
37                }
38            }
39            matches
40        }
41    }
42}
43
44pub fn serialize_to_json<'a, V: Debug + Clone + AsRef<str> + GetBytes>(data: &mut Vec<FlatJsonValue<V>>) -> Value<V> {
45    _serialize_to_json(data, 1)
46}
47
48pub fn serialize_to_json_with_option<'a, V: Debug + Clone + AsRef<str> + GetBytes>(data: &mut Vec<FlatJsonValue<V>>, root_depth: u8) -> Value<V> {
49    _serialize_to_json(data, root_depth)
50}
51
52pub fn _serialize_to_json<'a, V: Debug + Clone + AsRef<str> + GetBytes>(data: &mut Vec<FlatJsonValue<V>>, root_depth: u8) -> Value<V> {
53    let mut root = Value::Object(new_map::<V>(10));
54    let mut root_array = Value::Array(Vec::with_capacity(128));
55
56    let mut root_is_obj = true;
57
58    let sorted_data = data;
59    sorted_data.sort_unstable_by(|a, b|
60    // deepest values will go first, because we will iterate in reverse order from the array to pop value
61    match b.pointer.depth.cmp(&a.pointer.depth) {
62        Ordering::Equal => b.pointer.position.cmp(&a.pointer.position),
63        cmp => cmp,
64    }
65    );
66
67    let mut current_parent = &mut root;
68    let mut previous_parent_pointer: Vec<String> = Vec::with_capacity(10);
69    for _i in 0..sorted_data.len() {
70        let entry = sorted_data.pop().unwrap();
71        let key = entry.pointer;
72        let value = entry.value;
73
74        if key.pointer.is_empty() && matches!(key.value_type, ValueType::Array(_)) {
75            root_is_obj = false;
76            current_parent = &mut root_array;
77            continue;
78        }
79
80        if key.depth == root_depth {
81            match current_parent {
82                Value::Object(obj) => {
83                    let pointer = if root_depth == 1 {
84                        key.pointer[1..].to_owned()
85                    } else {
86                        key.pointer.splitn(root_depth as usize + 1, '/').last().unwrap().to_owned()
87                    };
88                    match key.value_type {
89                        ValueType::Object(parsed, elements) => {
90                            if parsed {
91                                obj.insert(pointer.to_owned(), Value::Object(new_map(elements)));
92                            } else {
93                                obj.insert(pointer.to_owned(), Value::ObjectSerialized(value.unwrap()));
94                            }
95                        }
96                        ValueType::Array(len) => {
97                            if let Some(value) = value {
98                                obj.insert(pointer.to_owned(), Value::ArraySerialized(value));
99                            } else {
100                                obj.insert(pointer.to_owned(), Value::Array(Vec::with_capacity(len)));
101                            }
102                        }
103                        _ => {
104                            let value1 = value_to_json(value, &key.value_type);
105                            if !matches!(value1, Value::Null) {
106                                obj.insert(pointer.to_owned(), value1);
107                            }
108                        }
109                    }
110                }
111                Value::Array(array) => {
112                    match key.value_type {
113                        ValueType::Object(parsed, elements) => {
114                            if parsed {
115                                array.push(Value::Object(new_map(elements)));
116                            } else {
117                                array.push(Value::ObjectSerialized(value.unwrap()));
118                            }
119                        }
120                        ValueType::Array(len) => {
121                            if let Some(value) = value {
122                                array.push(Value::ArraySerialized(value));
123                            } else {
124                                array.push(Value::Array(Vec::with_capacity(len)));
125                            }
126                        }
127                        _ => {
128                            let value1 = value_to_json(value, &key.value_type);
129                            if !matches!(value1, Value::Null) {
130                                array.push(value1);
131                            }
132                        }
133                    }
134                }
135                _ => panic!("only Object is accepted for root node")
136            }
137        } else if key.depth > root_depth {
138            let split = key.pointer.split('/');
139            let key_pointer_iter = split.filter(|s| !s.is_empty());
140            let start: usize = root_depth as usize - 1;
141            let key_pointer_len = key_pointer_iter.clone().count();
142
143            let mut should_update_current_parent = true;
144            if key_pointer_len > 0 {
145                should_update_current_parent = if previous_parent_pointer.len() != key_pointer_len - 1 {
146                    true
147                } else {
148                    let mut matches = true;
149                    for (i, s) in key_pointer_iter.clone().enumerate() {
150                        if i < start {
151                            continue;
152                        }
153                        if i == key_pointer_len - 1 {
154                            break;
155                        }
156                        if !previous_parent_pointer[i].eq(s) {
157                            matches = false;
158                            break;
159                        }
160                    }
161                    !matches
162                };
163            }
164
165            if should_update_current_parent {
166                previous_parent_pointer.clear();
167                if key_pointer_len > 0 {
168                    for (i, s) in key_pointer_iter.clone().enumerate() {
169                        if i < start {
170                            continue;
171                        }
172                        if i == key_pointer_len - 1 {
173                            break;
174                        }
175                        previous_parent_pointer.push(s.to_owned());
176                    }
177                }
178                let b = &previous_parent_pointer[0].as_bytes()[0];
179                if *b >= 0x30 && *b <= 0x39 {
180                    current_parent = &mut root_array;
181                } else {
182                    current_parent = &mut root;
183                }
184                for (i, s) in key_pointer_iter.clone().enumerate() {
185                    if i < start {
186                        continue;
187                    }
188                    if i == key_pointer_len - 1 {
189                        break;
190                    }
191                    match current_parent {
192                        Value::Object(ref mut obj) => {
193                            if obj.contains_key(s) {
194                                current_parent = obj.get_mut(s).unwrap();
195                            } else {
196                                obj.insert(s.to_owned(), Value::Object(new_map(10)));
197                                current_parent = obj.get_mut(s).unwrap();
198                            }
199                        }
200                        Value::Array(ref mut array) => {
201                            current_parent = array.get_mut(usize::from_str(s).unwrap())
202                                .unwrap();
203                            // .expect(format!("Expected to find parent at index for {}, current segment {}", key.pointer, s).as_str());
204                        }
205                        _ => panic!("only Object is accepted for root node")
206                    }
207                }
208            }
209
210            let k = key_pointer_iter.last().unwrap();
211            match current_parent {
212                Value::Object(obj) => {
213                    match key.value_type {
214                        ValueType::Object(parsed, elements) => {
215                            if parsed {
216                                obj.insert(k.to_owned(), Value::Object(new_map(elements)));
217                            } else {
218                                obj.insert(k.to_owned(), Value::ObjectSerialized(value.unwrap()));
219                            }
220                        }
221                        ValueType::Array(len) => {
222                            if let Some(value) = value {
223                                obj.insert(k.to_owned(), Value::ArraySerialized(value));
224                            } else {
225                                obj.insert(k.to_owned(), Value::Array(Vec::with_capacity(len)));
226                            }
227                        }
228                        _ => {
229                            let value1 = value_to_json(value, &key.value_type);
230                            if !matches!(value1, Value::Null) {
231                                obj.insert(k.to_owned(), value1);
232                            }
233                        }
234                    }
235                }
236                Value::Array(array) => {
237                    match key.value_type {
238                        ValueType::Object(parsed, elements) => {
239                            if parsed {
240                                array.push(Value::Object(new_map(elements)));
241                            } else {
242                                array.push(Value::ObjectSerialized(value.unwrap()));
243                            }
244                        }
245                        ValueType::Array(len) => {
246                            if let Some(value) = value {
247                                array.push(Value::ArraySerialized(value));
248                            } else {
249                                array.push(Value::Array(Vec::with_capacity(len)));
250                            }
251                        }
252                        _ => {
253                            let value1 = value_to_json(value, &key.value_type);
254                            if !matches!(value1, Value::Null) {
255                                array.push(value1);
256                            }
257                        }
258                    }
259                }
260                _ => panic!("only Object is accepted for root node")
261            }
262        }
263    }
264
265    if root_is_obj {
266        root
267    } else {
268        root_array
269    }
270}
271
272#[inline]
273fn new_map<V>(capacity: usize) -> Map<String, Value<V>> {
274    #[cfg(feature = "indexmap")]{
275        indexmap::IndexMap::with_capacity(capacity)
276    }
277    #[cfg(not(feature = "indexmap"))]{
278        std::collections::HashMap::new()
279    }
280}
281
282// Helper function to convert string values to JSON values based on ValueType
283fn value_to_json<V: Debug + Clone + AsRef<str> + GetBytes>(value: Option<V>, value_type: &ValueType) -> Value<V> {
284    if let Some(value) = value {
285        match value_type {
286            ValueType::Number => {
287                if let Ok(n) = value.as_ref().parse::<i64>() {
288                    Value::Integer(n)
289                } else {
290                    value.as_ref().parse::<f64>().map(Value::Number).unwrap_or(Value::Null)
291                }
292            },
293            ValueType::String => Value::String(value),
294            ValueType::Bool => Value::Bool(value.as_ref() == "true" || value.as_ref() == "1"),
295            ValueType::Null => Value::Null,
296            _ => Value::Null, // this should not happen as arrays and objects are handled separately
297        }
298    } else {
299        Value::Null
300    }
301}
302
303impl<V: ToString + AsRef<str>> Value<V> {
304    pub fn to_json(&self) -> String {
305        self._to_json(1)
306    }
307    fn _to_json(&self, depth: usize) -> String {
308        match self {
309            Value::Object(obj) => {
310                let members: Vec<String> = obj.iter()
311                    .filter(|(_, v)| !matches!(v, Value::Null))
312                    .map(|(k, v)| {
313                    format!("{:indent$}\"{}\": {}", "", k, v._to_json(depth + 1), indent = depth * 2)
314                }).collect();
315                format!("{{\n{}\n{:indent$}}}", members.join(",\n"), "", indent = (depth - 1) * 2)
316            }
317            Value::Array(arr) => {
318                let mut contains_nested_array = false;
319                let elements: Vec<String> = arr.iter()
320                    .filter(|v| !matches!(v, Value::Null))
321                    .map(|v| {
322                    if matches!(v, Value::Array(_)) || matches!(v, Value::Object(_)) {
323                        contains_nested_array = true;
324                        format!("{:indent$}{}", "", v._to_json(depth + 1), indent = (depth) * 2)
325                    } else {
326                        v._to_json(depth)
327                    }
328                }).collect();
329                if contains_nested_array {
330                    format!("[\n{}\n{:indent$}]", elements.join(",\n"), "", indent = (depth - 1) * 2)
331                } else {
332                    format!("[{}]", elements.join(", "))
333                }
334            }
335            Value::Number(num) => num.to_string(),
336            Value::Integer(num) => num.to_string(),
337            Value::String(s) => format!("\"{}\"", s.as_ref().replace('\"', "\\\"")),
338            Value::Bool(b) => b.to_string(),
339            Value::Null => "null".to_string(),
340            Value::ArraySerialized(value) => value.to_string(),
341            Value::ObjectSerialized(value) => value.to_string(),
342            _ => panic!("todo")
343        }
344    }
345}
346
347#[cfg(test)]
348#[cfg(feature = "indexmap")] // to ease testing we use indexmap to have deterministic output
349mod tests {
350    use crate::{FlatJsonValue, JSONParser, ParseOptions, PointerKey, ValueType};
351    use crate::serializer::{serialize_to_json, serialize_to_json_with_option};
352
353
354    #[test]
355    fn nested_object() {
356        let json =
357            r#"{
358  "id": 1,
359  "maxLevel": 99,
360  "name": "NV_BASIC",
361  "aaa": true,
362  "bbb": null,
363  "flags": {
364    "a": true,
365    "b": false,
366    "c": {
367      "nested": "Oui"
368    }
369  }
370}"#;
371let expected =
372            r#"{
373  "id": 1,
374  "maxLevel": 99,
375  "name": "NV_BASIC",
376  "aaa": true,
377  "flags": {
378    "a": true,
379    "b": false,
380    "c": {
381      "nested": "Oui"
382    }
383  }
384}"#;
385
386        let mut vec = JSONParser::parse(json, ParseOptions::default()).unwrap().json;
387        let value = serialize_to_json(&mut vec);
388        assert_eq!(value.to_json(), expected);
389    }
390    #[test]
391    fn missing_parent() {
392        let json =
393            r#"{
394  "id": 1,
395  "maxLevel": 99,
396  "name": "NV_BASIC",
397  "aaa": true,
398  "bbb": null
399}"#;
400        let expectation =
401            r#"{
402  "id": 1,
403  "maxLevel": 99,
404  "name": "NV_BASIC",
405  "aaa": true,
406  "damageFlags": {
407    "fire": true
408  }
409}"#;
410
411        let mut vec = JSONParser::parse(json, ParseOptions::default()).unwrap().json;
412        vec.push(FlatJsonValue {
413            pointer: PointerKey {
414                pointer: "/damageFlags/fire".to_string(),
415                value_type: ValueType::Bool,
416                depth: 2,
417                position: 0,
418                column_id: 0,
419            },
420            value: Some("true"),
421        });
422        // vec.push(FlatJsonValue{
423        //     pointer: PointerKey {
424        //         pointer: "/requires/spPerLevel/0/level".to_string(),
425        //         value_type: ValueType::Number,
426        //         depth: 4,
427        //         index: 0,
428        //         position: 0,
429        //     },
430        //     value: Some("11"),
431        // });
432        let value = serialize_to_json(&mut vec);
433        assert_eq!(value.to_json(), expectation);
434    }
435
436    #[test]
437    fn lifetime_test() {
438        let result = {
439            let json =
440                r#"{
441  "id": 1,
442  "maxLevel": 99,
443  "name": "NV_BASIC",
444  "aaa": true,
445  "bbb": null,
446  "flags": {
447    "a": true,
448    "b": false,
449    "c": {
450      "nested": "Oui"
451    }
452  }
453}"#;
454
455            JSONParser::parse(json, ParseOptions::default()).unwrap()
456        };
457        let mut vec = result.json;
458        vec[0].value = Some("12");
459        let value = serialize_to_json(&mut vec);
460        println!("{:?}", value.to_json());
461    }
462
463    #[test]
464    fn simple_array() {
465        let json =
466            r#"[1, 2, 3]"#;
467
468        let res = JSONParser::parse(json, ParseOptions::default()).unwrap();
469        let mut vec = res.json;
470        let value = serialize_to_json(&mut vec);
471        assert_eq!(value.to_json(), json);
472    }
473
474    #[test]
475    fn array_of_object() {
476        let json =
477            r#"[
478  {
479    "id": 1,
480    "maxLevel": 99,
481    "name": "NV_BASIC",
482    "aaa": true,
483    "flags": {
484      "a": true,
485      "b": false,
486      "c": {
487        "nested": "Oui"
488      }
489    }
490  },
491  {
492    "id": 2,
493    "maxLevel": 10,
494    "name": "BASH",
495    "flags": {
496      "a": true,
497      "b": false,
498      "c": {
499        "nested": "Oui"
500      }
501    }
502  }
503]"#;
504
505        let res = JSONParser::parse(json, ParseOptions::default()).unwrap();
506        let mut vec = res.json;
507        let value = serialize_to_json(&mut vec);
508        assert_eq!(value.to_json(), json);
509    }
510
511    #[test]
512    fn array_of_array() {
513        let json =
514            r#"[
515  [1, 2, 3],
516  [6, 7, 8]
517]"#;
518
519        let res = JSONParser::parse(json, ParseOptions::default()).unwrap();
520        let mut vec = res.json;
521        let value = serialize_to_json(&mut vec);
522        assert_eq!(value.to_json(), json);
523    }
524
525    #[test]
526    fn actual_test_data() {
527        let json =
528            r#"{
529  "skills": [
530    {
531      "description": "Basic Skill",
532      "id": 1,
533      "maxLevel": 9,
534      "name": "NV_BASIC",
535      "basicSkillPerLevel": [
536        {
537          "level": 1,
538          "value": "Trade"
539        },
540        {
541          "level": 2,
542          "value": "Emoticon"
543        },
544        {
545          "level": 3,
546          "value": "Sit"
547        },
548        {
549          "level": 4,
550          "value": "Chat Room (create)"
551        },
552        {
553          "level": 5,
554          "value": "Party (join)"
555        },
556        {
557          "level": 6,
558          "value": "Kafra Storage"
559        },
560        {
561          "level": 7,
562          "value": "Party (create)"
563        },
564        {
565          "level": 8,
566          "value": "-"
567        },
568        {
569          "level": 9,
570          "value": "Job Change"
571        }
572      ],
573      "targetType": "Passive"
574    },
575    {
576      "description": "Sword Mastery",
577      "id": 2,
578      "maxLevel": 10,
579      "name": "SM_SWORD",
580      "type": "Weapon",
581      "requires": {
582        "spCostPerLevel": [
583          {
584            "level": 1,
585            "value": 10
586          },
587          {
588            "level": 2,
589            "value": 20
590          },
591          {
592            "level": 3,
593            "value": 30
594          }
595        ]
596      },
597      "bonusToSelf": [
598        {
599          "level": 1,
600          "value": {
601            "bonus": "MasteryDamageUsingWeaponType",
602            "value": "1hSword",
603            "value2": 4
604          }
605        },
606        {
607          "level": 2,
608          "value": {
609            "bonus": "MasteryDamageUsingWeaponType",
610            "value": "1hSword",
611            "value2": 8
612          }
613        },
614        {
615          "level": 3,
616          "value": {
617            "bonus": "MasteryDamageUsingWeaponType",
618            "value": "1hSword",
619            "value2": 12
620          }
621        },
622        {
623          "level": 4,
624          "value": {
625            "bonus": "MasteryDamageUsingWeaponType",
626            "value": "1hSword",
627            "value2": 16
628          }
629        },
630        {
631          "level": 5,
632          "value": {
633            "bonus": "MasteryDamageUsingWeaponType",
634            "value": "1hSword",
635            "value2": 20
636          }
637        },
638        {
639          "level": 6,
640          "value": {
641            "bonus": "MasteryDamageUsingWeaponType",
642            "value": "1hSword",
643            "value2": 24
644          }
645        },
646        {
647          "level": 7,
648          "value": {
649            "bonus": "MasteryDamageUsingWeaponType",
650            "value": "1hSword",
651            "value2": 28
652          }
653        },
654        {
655          "level": 8,
656          "value": {
657            "bonus": "MasteryDamageUsingWeaponType",
658            "value": "1hSword",
659            "value2": 32
660          }
661        },
662        {
663          "level": 9,
664          "value": {
665            "bonus": "MasteryDamageUsingWeaponType",
666            "value": "1hSword",
667            "value2": 36
668          }
669        },
670        {
671          "level": 10,
672          "value": {
673            "bonus": "MasteryDamageUsingWeaponType",
674            "value": "1hSword",
675            "value2": 40
676          }
677        }
678      ],
679      "targetType": "Passive"
680    }
681  ]
682}"#;
683        let res = JSONParser::parse(json, ParseOptions::default()).unwrap();
684        let mut vec = res.json;
685        let value = serialize_to_json(&mut vec);
686        assert_eq!(value.to_json(), json);
687
688        let res = JSONParser::parse(json, ParseOptions::default().max_depth(2)).unwrap();
689        let json_depth_2 = res.json;
690
691        // Test partial serialization of nested object
692        let res = JSONParser::parse(json, ParseOptions::default()).unwrap();
693        let vec = res.json;
694        let mut vec: Vec<FlatJsonValue<&str>> = vec.iter().filter(|entry| entry.pointer.depth >= 3 && entry.pointer.pointer.starts_with("/skills/0")).cloned().collect::<Vec<FlatJsonValue<&str>>>();
695        let value = serialize_to_json_with_option(&mut vec, 3);
696        assert_eq!(value.to_json().replace(' ', ""), json_depth_2[1].value.unwrap().replace(' ', ""));
697
698        // Test partial serialization of nested object
699        let res = JSONParser::parse(json, ParseOptions::default()).unwrap();
700        let vec = res.json;
701        let mut vec: Vec<FlatJsonValue<&str>> = vec.iter().filter(|entry| entry.pointer.depth >= 3 && entry.pointer.pointer.starts_with("/skills/1")).cloned().collect::<Vec<FlatJsonValue<&str>>>();
702        let value = serialize_to_json_with_option(&mut vec, 3);
703        assert_eq!(value.to_json().replace(' ', ""), json_depth_2[2].value.unwrap().replace(' ', ""));
704
705
706        let res = JSONParser::parse(json, ParseOptions::default().start_parse_at("/skills".to_string()).parse_array(false)).unwrap();
707        let json_depth_2 = res.json;
708
709        // Test partial serialization of nested parsed array
710        let res = JSONParser::parse(json, ParseOptions::default()).unwrap();
711        let vec = res.json;
712        let mut vec: Vec<FlatJsonValue<&str>> = vec.iter().filter(|entry| entry.pointer.depth >= 4 && entry.pointer.pointer.starts_with("/skills/1/bonusToSelf")).cloned().collect::<Vec<FlatJsonValue<&str>>>();
713        vec.push(FlatJsonValue {
714            pointer: PointerKey {
715                pointer: "".to_string(),
716                value_type: ValueType::Array(10),
717                depth: 0,
718                position: 0,
719                column_id: 0,
720            },
721            value: None,
722        });
723        let value = serialize_to_json_with_option(&mut vec, 4);
724        assert_eq!(value.to_json().replace(' ', ""), json_depth_2[16].value.unwrap().replace(' ', ""));
725
726        // Test partial serialization of nested parsed array under object
727        let res = JSONParser::parse(json, ParseOptions::default()).unwrap();
728        let vec = res.json;
729        let mut vec: Vec<FlatJsonValue<&str>> = vec.iter().filter(|entry| entry.pointer.depth >= 5 && entry.pointer.pointer.starts_with("/skills/1/requires/spCostPerLevel")).cloned().collect::<Vec<FlatJsonValue<&str>>>();
730        vec.push(FlatJsonValue {
731            pointer: PointerKey {
732                pointer: "".to_string(),
733                value_type: ValueType::Array(10),
734                depth: 0,
735                position: 0,
736                column_id: 0,
737            },
738            value: None,
739        });
740        let value = serialize_to_json_with_option(&mut vec, 5);
741        assert_eq!(value.to_json().replace(' ', ""), json_depth_2[15].value.unwrap().replace(' ', ""));
742    }
743
744    #[test]
745    fn actual_test_data_start_at() {
746        let json =
747            r#"{
748  "skills": [
749    {
750      "description": "Basic Skill",
751      "id": 1,
752      "maxLevel": 9,
753      "name": "NV_BASIC",
754      "basicSkillPerLevel": [{
755          "level": 1,
756          "value": "Trade"
757        },
758        {
759          "level": 2,
760          "value": "Emoticon"
761        },
762        {
763          "level": 3,
764          "value": "Sit"
765        },
766        {
767          "level": 4,
768          "value": "Chat Room (create)"
769        },
770        {
771          "level": 5,
772          "value": "Party (join)"
773        },
774        {
775          "level": 6,
776          "value": "Kafra Storage"
777        },
778        {
779          "level": 7,
780          "value": "Party (create)"
781        },
782        {
783          "level": 8,
784          "value": "-"
785        },
786        {
787          "level": 9,
788          "value": "Job Change"
789        }
790      ],
791      "targetType": "Passive"
792    },
793    {
794      "description": "Sword Mastery",
795      "id": 2,
796      "maxLevel": 10,
797      "name": "SM_SWORD",
798      "type": "Weapon",
799      "bonusToSelf": [{
800          "level": 1,
801          "value": {
802            "bonus": "MasteryDamageUsingWeaponType",
803            "value": "1hSword",
804            "value2": 4
805          }
806        },
807        {
808          "level": 2,
809          "value": {
810            "bonus": "MasteryDamageUsingWeaponType",
811            "value": "1hSword",
812            "value2": 8
813          }
814        },
815        {
816          "level": 3,
817          "value": {
818            "bonus": "MasteryDamageUsingWeaponType",
819            "value": "1hSword",
820            "value2": 12
821          }
822        },
823        {
824          "level": 4,
825          "value": {
826            "bonus": "MasteryDamageUsingWeaponType",
827            "value": "1hSword",
828            "value2": 16
829          }
830        },
831        {
832          "level": 5,
833          "value": {
834            "bonus": "MasteryDamageUsingWeaponType",
835            "value": "1hSword",
836            "value2": 20
837          }
838        },
839        {
840          "level": 6,
841          "value": {
842            "bonus": "MasteryDamageUsingWeaponType",
843            "value": "1hSword",
844            "value2": 24
845          }
846        },
847        {
848          "level": 7,
849          "value": {
850            "bonus": "MasteryDamageUsingWeaponType",
851            "value": "1hSword",
852            "value2": 28
853          }
854        },
855        {
856          "level": 8,
857          "value": {
858            "bonus": "MasteryDamageUsingWeaponType",
859            "value": "1hSword",
860            "value2": 32
861          }
862        },
863        {
864          "level": 9,
865          "value": {
866            "bonus": "MasteryDamageUsingWeaponType",
867            "value": "1hSword",
868            "value2": 36
869          }
870        },
871        {
872          "level": 10,
873          "value": {
874            "bonus": "MasteryDamageUsingWeaponType",
875            "value": "1hSword",
876            "value2": 40
877          }
878        }
879      ],
880      "targetType": "Passive"
881    }
882  ]
883}"#;
884        let res = JSONParser::parse(json, ParseOptions::default().start_parse_at("/skills".to_string()).parse_array(false)).unwrap();
885        let mut vec = res.json;
886        let value = serialize_to_json(&mut vec);
887        assert_eq!(value.to_json(), json);
888    }
889
890    #[test]
891    fn actual_test_data_max_depth() {
892        let json =
893            r#"{
894  "skills": [{
895      "description": "Basic Skill",
896      "id": 1,
897      "maxLevel": 9,
898      "name": "NV_BASIC",
899      "basicSkillPerLevel": [{
900          "level": 1,
901          "value": "Trade"
902        },
903        {
904          "level": 2,
905          "value": "Emoticon"
906        },
907        {
908          "level": 3,
909          "value": "Sit"
910        },
911        {
912          "level": 4,
913          "value": "Chat Room (create)"
914        },
915        {
916          "level": 5,
917          "value": "Party (join)"
918        },
919        {
920          "level": 6,
921          "value": "Kafra Storage"
922        },
923        {
924          "level": 7,
925          "value": "Party (create)"
926        },
927        {
928          "level": 8,
929          "value": "-"
930        },
931        {
932          "level": 9,
933          "value": "Job Change"
934        }
935      ],
936      "targetType": "Passive"
937    },
938    {
939      "description": "Sword Mastery",
940      "id": 2,
941      "maxLevel": 10,
942      "name": "SM_SWORD",
943      "type": "Weapon",
944      "bonusToSelf": [{
945          "level": 1,
946          "value": {
947            "bonus": "MasteryDamageUsingWeaponType",
948            "value": "1hSword",
949            "value2": 4
950          }
951        },
952        {
953          "level": 2,
954          "value": {
955            "bonus": "MasteryDamageUsingWeaponType",
956            "value": "1hSword",
957            "value2": 8
958          }
959        },
960        {
961          "level": 3,
962          "value": {
963            "bonus": "MasteryDamageUsingWeaponType",
964            "value": "1hSword",
965            "value2": 12
966          }
967        },
968        {
969          "level": 4,
970          "value": {
971            "bonus": "MasteryDamageUsingWeaponType",
972            "value": "1hSword",
973            "value2": 16
974          }
975        },
976        {
977          "level": 5,
978          "value": {
979            "bonus": "MasteryDamageUsingWeaponType",
980            "value": "1hSword",
981            "value2": 20
982          }
983        },
984        {
985          "level": 6,
986          "value": {
987            "bonus": "MasteryDamageUsingWeaponType",
988            "value": "1hSword",
989            "value2": 24
990          }
991        },
992        {
993          "level": 7,
994          "value": {
995            "bonus": "MasteryDamageUsingWeaponType",
996            "value": "1hSword",
997            "value2": 28
998          }
999        },
1000        {
1001          "level": 8,
1002          "value": {
1003            "bonus": "MasteryDamageUsingWeaponType",
1004            "value": "1hSword",
1005            "value2": 32
1006          }
1007        },
1008        {
1009          "level": 9,
1010          "value": {
1011            "bonus": "MasteryDamageUsingWeaponType",
1012            "value": "1hSword",
1013            "value2": 36
1014          }
1015        },
1016        {
1017          "level": 10,
1018          "value": {
1019            "bonus": "MasteryDamageUsingWeaponType",
1020            "value": "1hSword",
1021            "value2": 40
1022          }
1023        }
1024      ],
1025      "targetType": "Passive"
1026    }
1027  ]
1028}"#;
1029
1030        let res = JSONParser::parse(json, ParseOptions::default().max_depth(1).parse_array(true)).unwrap();
1031        let mut vec = res.json;
1032        let value = serialize_to_json(&mut vec);
1033        assert_eq!(value.to_json(), json);
1034    }
1035
1036
1037    #[test]
1038    fn actual_test_data_max_depth_parse_array_false() {
1039        let json =
1040            r#"{
1041  "skills": [{
1042      "description": "Basic Skill",
1043      "id": 1,
1044      "maxLevel": 9,
1045      "name": "NV_BASIC",
1046      "basicSkillPerLevel": [{
1047          "level": 1,
1048          "value": "Trade"
1049        },
1050        {
1051          "level": 2,
1052          "value": "Emoticon"
1053        },
1054        {
1055          "level": 3,
1056          "value": "Sit"
1057        },
1058        {
1059          "level": 4,
1060          "value": "Chat Room (create)"
1061        },
1062        {
1063          "level": 5,
1064          "value": "Party (join)"
1065        },
1066        {
1067          "level": 6,
1068          "value": "Kafra Storage"
1069        },
1070        {
1071          "level": 7,
1072          "value": "Party (create)"
1073        },
1074        {
1075          "level": 8,
1076          "value": "-"
1077        },
1078        {
1079          "level": 9,
1080          "value": "Job Change"
1081        }
1082      ],
1083      "targetType": "Passive"
1084    },
1085    {
1086      "description": "Sword Mastery",
1087      "id": 2,
1088      "maxLevel": 10,
1089      "name": "SM_SWORD",
1090      "type": "Weapon",
1091      "bonusToSelf": [{
1092          "level": 1,
1093          "value": {
1094            "bonus": "MasteryDamageUsingWeaponType",
1095            "value": "1hSword",
1096            "value2": 4
1097          }
1098        },
1099        {
1100          "level": 2,
1101          "value": {
1102            "bonus": "MasteryDamageUsingWeaponType",
1103            "value": "1hSword",
1104            "value2": 8
1105          }
1106        },
1107        {
1108          "level": 3,
1109          "value": {
1110            "bonus": "MasteryDamageUsingWeaponType",
1111            "value": "1hSword",
1112            "value2": 12
1113          }
1114        },
1115        {
1116          "level": 4,
1117          "value": {
1118            "bonus": "MasteryDamageUsingWeaponType",
1119            "value": "1hSword",
1120            "value2": 16
1121          }
1122        },
1123        {
1124          "level": 5,
1125          "value": {
1126            "bonus": "MasteryDamageUsingWeaponType",
1127            "value": "1hSword",
1128            "value2": 20
1129          }
1130        },
1131        {
1132          "level": 6,
1133          "value": {
1134            "bonus": "MasteryDamageUsingWeaponType",
1135            "value": "1hSword",
1136            "value2": 24
1137          }
1138        },
1139        {
1140          "level": 7,
1141          "value": {
1142            "bonus": "MasteryDamageUsingWeaponType",
1143            "value": "1hSword",
1144            "value2": 28
1145          }
1146        },
1147        {
1148          "level": 8,
1149          "value": {
1150            "bonus": "MasteryDamageUsingWeaponType",
1151            "value": "1hSword",
1152            "value2": 32
1153          }
1154        },
1155        {
1156          "level": 9,
1157          "value": {
1158            "bonus": "MasteryDamageUsingWeaponType",
1159            "value": "1hSword",
1160            "value2": 36
1161          }
1162        },
1163        {
1164          "level": 10,
1165          "value": {
1166            "bonus": "MasteryDamageUsingWeaponType",
1167            "value": "1hSword",
1168            "value2": 40
1169          }
1170        }
1171      ],
1172      "targetType": "Passive"
1173    }
1174  ]
1175}"#;
1176
1177        let res = JSONParser::parse(json, ParseOptions::default().max_depth(1).parse_array(false)).unwrap();
1178        let mut vec = res.json;
1179        let value = serialize_to_json(&mut vec);
1180        assert_eq!(value.to_json(), json);
1181    }
1182
1183    #[test]
1184    fn actual_test_data_max2_depth_parse_array_false() {
1185        let json =
1186            r#"{
1187  "skills": [
1188    {
1189      "description": "Basic Skill",
1190      "id": 1,
1191      "maxLevel": 9,
1192      "name": "NV_BASIC",
1193      "basicSkillPerLevel": [{
1194          "level": 1,
1195          "value": "Trade"
1196        },
1197        {
1198          "level": 2,
1199          "value": "Emoticon"
1200        },
1201        {
1202          "level": 3,
1203          "value": "Sit"
1204        },
1205        {
1206          "level": 4,
1207          "value": "Chat Room (create)"
1208        },
1209        {
1210          "level": 5,
1211          "value": "Party (join)"
1212        },
1213        {
1214          "level": 6,
1215          "value": "Kafra Storage"
1216        },
1217        {
1218          "level": 7,
1219          "value": "Party (create)"
1220        },
1221        {
1222          "level": 8,
1223          "value": "-"
1224        },
1225        {
1226          "level": 9,
1227          "value": "Job Change"
1228        }
1229      ],
1230      "targetType": "Passive"
1231    },
1232    {
1233      "description": "Sword Mastery",
1234      "id": 2,
1235      "maxLevel": 10,
1236      "name": "SM_SWORD",
1237      "type": "Weapon",
1238      "bonusToSelf": [{
1239          "level": 1,
1240          "value": {
1241            "bonus": "MasteryDamageUsingWeaponType",
1242            "value": "1hSword",
1243            "value2": 4
1244          }
1245        },
1246        {
1247          "level": 2,
1248          "value": {
1249            "bonus": "MasteryDamageUsingWeaponType",
1250            "value": "1hSword",
1251            "value2": 8
1252          }
1253        },
1254        {
1255          "level": 3,
1256          "value": {
1257            "bonus": "MasteryDamageUsingWeaponType",
1258            "value": "1hSword",
1259            "value2": 12
1260          }
1261        },
1262        {
1263          "level": 4,
1264          "value": {
1265            "bonus": "MasteryDamageUsingWeaponType",
1266            "value": "1hSword",
1267            "value2": 16
1268          }
1269        },
1270        {
1271          "level": 5,
1272          "value": {
1273            "bonus": "MasteryDamageUsingWeaponType",
1274            "value": "1hSword",
1275            "value2": 20
1276          }
1277        },
1278        {
1279          "level": 6,
1280          "value": {
1281            "bonus": "MasteryDamageUsingWeaponType",
1282            "value": "1hSword",
1283            "value2": 24
1284          }
1285        },
1286        {
1287          "level": 7,
1288          "value": {
1289            "bonus": "MasteryDamageUsingWeaponType",
1290            "value": "1hSword",
1291            "value2": 28
1292          }
1293        },
1294        {
1295          "level": 8,
1296          "value": {
1297            "bonus": "MasteryDamageUsingWeaponType",
1298            "value": "1hSword",
1299            "value2": 32
1300          }
1301        },
1302        {
1303          "level": 9,
1304          "value": {
1305            "bonus": "MasteryDamageUsingWeaponType",
1306            "value": "1hSword",
1307            "value2": 36
1308          }
1309        },
1310        {
1311          "level": 10,
1312          "value": {
1313            "bonus": "MasteryDamageUsingWeaponType",
1314            "value": "1hSword",
1315            "value2": 40
1316          }
1317        }
1318      ],
1319      "damageFlags": {
1320        "noDamage": true
1321      },
1322      "targetType": "Passive"
1323    }
1324  ]
1325}"#;
1326
1327        let res = JSONParser::parse(json, ParseOptions::default().max_depth(2).start_parse_at("/skills".to_string()).parse_array(false)).unwrap();
1328        let mut vec = res.json;
1329        let value = serialize_to_json(&mut vec);
1330        assert_eq!(value.to_json(), json);
1331    }
1332
1333
1334    #[cfg(feature = "serde")]
1335    #[test]
1336    fn serde_serialization() {
1337        let json =
1338            r#"{
1339  "skills": [
1340    {
1341      "description": "Basic Skill",
1342      "id": 1,
1343      "maxLevel": 9,
1344      "name": "NV_BASIC",
1345      "basicSkillPerLevel": [{
1346          "level": 1,
1347          "value": "Trade"
1348        },
1349        {
1350          "level": 2,
1351          "value": "Emoticon"
1352        },
1353        {
1354          "level": 3,
1355          "value": "Sit"
1356        },
1357        {
1358          "level": 4,
1359          "value": "Chat Room (create)"
1360        },
1361        {
1362          "level": 5,
1363          "value": "Party (join)"
1364        },
1365        {
1366          "level": 6,
1367          "value": "Kafra Storage"
1368        },
1369        {
1370          "level": 7,
1371          "value": "Party (create)"
1372        },
1373        {
1374          "level": 8,
1375          "value": "-"
1376        },
1377        {
1378          "level": 9,
1379          "value": "Job Change"
1380        }
1381      ],
1382      "targetType": "Passive"
1383    },
1384    {
1385      "description": "Sword Mastery",
1386      "id": 2,
1387      "maxLevel": 10,
1388      "name": "SM_SWORD",
1389      "type": "Weapon",
1390      "bonusToSelf": [{
1391          "level": 1,
1392          "value": {
1393            "bonus": "MasteryDamageUsingWeaponType",
1394            "value": "1hSword",
1395            "value2": 4
1396          }
1397        },
1398        {
1399          "level": 2,
1400          "value": {
1401            "bonus": "MasteryDamageUsingWeaponType",
1402            "value": "1hSword",
1403            "value2": 8
1404          }
1405        },
1406        {
1407          "level": 3,
1408          "value": {
1409            "bonus": "MasteryDamageUsingWeaponType",
1410            "value": "1hSword",
1411            "value2": 12
1412          }
1413        },
1414        {
1415          "level": 4,
1416          "value": {
1417            "bonus": "MasteryDamageUsingWeaponType",
1418            "value": "1hSword",
1419            "value2": 16
1420          }
1421        },
1422        {
1423          "level": 5,
1424          "value": {
1425            "bonus": "MasteryDamageUsingWeaponType",
1426            "value": "1hSword",
1427            "value2": 20
1428          }
1429        },
1430        {
1431          "level": 6,
1432          "value": {
1433            "bonus": "MasteryDamageUsingWeaponType",
1434            "value": "1hSword",
1435            "value2": 24
1436          }
1437        },
1438        {
1439          "level": 7,
1440          "value": {
1441            "bonus": "MasteryDamageUsingWeaponType",
1442            "value": "1hSword",
1443            "value2": 28
1444          }
1445        },
1446        {
1447          "level": 8,
1448          "value": {
1449            "bonus": "MasteryDamageUsingWeaponType",
1450            "value": "1hSword",
1451            "value2": 32
1452          }
1453        },
1454        {
1455          "level": 9,
1456          "value": {
1457            "bonus": "MasteryDamageUsingWeaponType",
1458            "value": "1hSword",
1459            "value2": 36
1460          }
1461        },
1462        {
1463          "level": 10,
1464          "value": {
1465            "bonus": "MasteryDamageUsingWeaponType",
1466            "value": "1hSword",
1467            "value2": 40
1468          }
1469        }
1470      ],
1471      "damageFlags": {
1472        "noDamage": true
1473      },
1474      "targetType": "Passive"
1475    }
1476  ]
1477}"#;
1478
1479        let res = JSONParser::parse(json, ParseOptions::default().max_depth(2).start_parse_at("/skills".to_string()).parse_array(false)).unwrap();
1480        let mut vec = res.json;
1481        let value = serialize_to_json(&mut vec);
1482        let res = serde_json::to_string_pretty(&value);
1483        assert_eq!(res.unwrap(), json);
1484    }
1485}
1486
1487#[cfg(feature = "serde")]
1488impl<V: serde::ser::Serialize + AsRef<str>> serde::ser::Serialize for Value<V> {
1489    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1490    where
1491        S: serde::ser::Serializer,
1492    {
1493        use serde_json::value::RawValue;
1494        use serde::ser::{SerializeMap, SerializeSeq};
1495        match self {
1496            Value::Object(map) => {
1497                let mut map_serializer = serializer.serialize_map(Some(map.len()))?;
1498                for (k, v) in map {
1499                    map_serializer.serialize_entry(k, v)?;
1500                }
1501                map_serializer.end()
1502            }
1503            Value::ObjectSerialized(v) => {
1504                RawValue::from_string(v.as_ref().to_string()).unwrap().serialize(serializer)
1505            },
1506            Value::Array(vec) => {
1507                let mut seq_serializer = serializer.serialize_seq(Some(vec.len()))?;
1508                for item in vec {
1509                    seq_serializer.serialize_element(item)?;
1510                }
1511                seq_serializer.end()
1512            }
1513            Value::ArraySerialized(v) => {
1514                RawValue::from_string(v.as_ref().to_string()).unwrap().serialize(serializer)
1515            },
1516            Value::Number(n) => serializer.serialize_f64(*n),
1517            Value::Integer(n) => serializer.serialize_i64(*n),
1518            Value::String(v) => v.serialize(serializer),
1519            Value::Bool(b) => serializer.serialize_bool(*b),
1520            Value::Null => serializer.serialize_unit(),
1521        }
1522    }
1523}