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 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 }
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
282fn 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, }
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")] mod 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 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 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 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 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 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}