1use crate::{
46 Encoding, TextToken,
47 text::{ArrayReader, GroupEntry, ObjectReader, Operator, ScalarReader, ValueReader},
48};
49use serde::{
50 Serialize, Serializer,
51 ser::{SerializeMap, SerializeSeq},
52};
53use std::ops::Deref;
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57pub struct JsonOptions {
58 pretty: bool,
60
61 duplicate_keys: DuplicateKeyMode,
63
64 type_narrowing: TypeNarrowing,
66}
67
68impl JsonOptions {
69 pub fn new() -> Self {
71 JsonOptions::default()
72 }
73
74 pub fn with_prettyprint(mut self, pretty: bool) -> JsonOptions {
76 self.pretty = pretty;
77 self
78 }
79
80 pub fn with_duplicate_keys(mut self, duplicate_keys: DuplicateKeyMode) -> JsonOptions {
82 self.duplicate_keys = duplicate_keys;
83 self
84 }
85
86 pub fn with_type_narrowing(mut self, type_narrowing: TypeNarrowing) -> JsonOptions {
88 self.type_narrowing = type_narrowing;
89 self
90 }
91
92 pub(crate) fn output_len_factor(&self) -> usize {
97 match (self.pretty, self.duplicate_keys) {
98 (false, DuplicateKeyMode::Group | DuplicateKeyMode::Preserve) => 10,
99 (true, DuplicateKeyMode::Group | DuplicateKeyMode::Preserve) => 20,
100 (false, DuplicateKeyMode::KeyValuePairs) => 15,
101 (true, DuplicateKeyMode::KeyValuePairs) => 60,
102 }
103 }
104}
105
106impl Default for JsonOptions {
107 fn default() -> Self {
108 Self {
109 pretty: false,
110 duplicate_keys: DuplicateKeyMode::Preserve,
111 type_narrowing: TypeNarrowing::All,
112 }
113 }
114}
115
116#[derive(Debug, Clone, Copy, PartialEq, Eq)]
118pub enum TypeNarrowing {
119 All,
139
140 Unquoted,
160
161 None,
181}
182
183#[derive(Debug, Clone, Copy, PartialEq, Eq)]
195pub enum DuplicateKeyMode {
196 Group,
225
226 Preserve,
252
253 KeyValuePairs,
287}
288
289fn writer_json<W, S>(writer: W, pretty: bool, ser: S) -> Result<(), std::io::Error>
290where
291 W: std::io::Write,
292 S: serde::Serialize,
293{
294 let result = if pretty {
295 serde_json::to_writer_pretty(writer, &ser)
296 } else {
297 serde_json::to_writer(writer, &ser)
298 };
299
300 result.map_err(|e| e.into())
301}
302
303fn vec_json<F>(mut out: Vec<u8>, write_fn: F) -> Vec<u8>
304where
305 F: FnOnce(&mut Vec<u8>) -> Result<(), std::io::Error>,
306{
307 if let Err(e) = write_fn(&mut out) {
311 panic!("failed to serialize json to vector: {}", e)
312 } else {
313 out
314 }
315}
316
317fn string_json(json: Vec<u8>) -> String {
318 unsafe { String::from_utf8_unchecked(json) }
320}
321
322pub struct JsonObjectBuilder<'data, 'tokens, E> {
324 reader: ObjectReader<'data, 'tokens, E>,
325 options: JsonOptions,
326}
327
328fn is_key_value_pattern<E>(reader: &ArrayReader<'_, '_, E>) -> bool
330where
331 E: Encoding + Clone,
332{
333 let mut values = reader.values();
334 let mut has_key_value_pairs = false;
335
336 while let Some(current) = values.next() {
337 if current.token() == &TextToken::MixedContainer {
339 continue;
340 }
341
342 if current.read_scalar().is_err() {
343 return false;
344 }
345
346 let Some(next) = values.next() else {
347 return false;
348 };
349
350 if !matches!(next.token(), TextToken::Operator(_)) {
351 return false;
352 }
353
354 has_key_value_pairs = true;
355 values.next(); }
357
358 has_key_value_pairs
359}
360
361fn serialize_key_value_patterns<S, E>(
363 reader: &ArrayReader<'_, '_, E>,
364 map: &mut <S as Serializer>::SerializeMap,
365 options: JsonOptions,
366) -> Result<(), S::Error>
367where
368 S: Serializer,
369 E: Encoding + Clone,
370{
371 let mut values = reader.values();
372
373 while let Some(key_val) = values.next() {
374 if key_val.token() == &TextToken::MixedContainer {
376 continue;
377 }
378
379 let Ok(key_scalar) = key_val.read_scalar() else {
380 break;
381 };
382
383 let Some(op_val) = values.next() else {
384 break;
385 };
386
387 let TextToken::Operator(op) = op_val.token() else {
388 break;
389 };
390
391 let Some(value_val) = values.next() else {
392 break;
393 };
394
395 let v = OperatorValue {
396 operator: if *op == crate::text::Operator::Equal {
397 None
398 } else {
399 Some(*op)
400 },
401 value: value_val,
402 options,
403 };
404 map.serialize_entry(&key_scalar.to_string(), &v)?;
405 }
406
407 Ok(())
408}
409
410impl<E> JsonObjectBuilder<'_, '_, E>
411where
412 E: Encoding + Clone,
413{
414 pub fn with_options(mut self, options: JsonOptions) -> Self {
416 self.options = options;
417 self
418 }
419
420 pub fn to_writer<W>(self, writer: W) -> Result<(), std::io::Error>
422 where
423 W: std::io::Write,
424 {
425 writer_json(writer, self.options.pretty, &self)
426 }
427
428 pub fn to_vec(self) -> Vec<u8> {
430 let out = Vec::with_capacity(self.reader.tokens_len() * self.options.output_len_factor());
431 vec_json(out, |x| self.to_writer(x))
432 }
433
434 #[allow(clippy::inherent_to_string)]
436 pub fn to_string(self) -> String {
437 string_json(self.to_vec())
438 }
439}
440
441impl<'data, 'tokens, E> ObjectReader<'data, 'tokens, E>
442where
443 E: Encoding + Clone,
444{
445 pub fn json(&self) -> JsonObjectBuilder<'data, 'tokens, E> {
447 JsonObjectBuilder {
448 reader: self.clone(),
449 options: JsonOptions::default(),
450 }
451 }
452}
453
454pub struct JsonArrayBuilder<'data, 'tokens, E> {
456 reader: ArrayReader<'data, 'tokens, E>,
457 options: JsonOptions,
458}
459
460impl<E> JsonArrayBuilder<'_, '_, E>
461where
462 E: Encoding + Clone,
463{
464 pub fn with_options(mut self, options: JsonOptions) -> Self {
466 self.options = options;
467 self
468 }
469
470 pub fn to_writer<W>(self, writer: W) -> Result<(), std::io::Error>
472 where
473 W: std::io::Write,
474 {
475 writer_json(writer, self.options.pretty, &self)
476 }
477
478 pub fn to_vec(self) -> Vec<u8> {
480 let out = Vec::with_capacity(self.reader.tokens_len() * self.options.output_len_factor());
481 vec_json(out, |x| self.to_writer(x))
482 }
483
484 #[allow(clippy::inherent_to_string)]
486 pub fn to_string(self) -> String {
487 string_json(self.to_vec())
488 }
489}
490
491impl<'data, 'tokens, E> ArrayReader<'data, 'tokens, E>
492where
493 E: Encoding + Clone,
494{
495 pub fn json(&self) -> JsonArrayBuilder<'data, 'tokens, E> {
497 JsonArrayBuilder {
498 reader: self.clone(),
499 options: JsonOptions::default(),
500 }
501 }
502}
503
504pub struct JsonValueBuilder<'data, 'tokens, E> {
506 reader: ValueReader<'data, 'tokens, E>,
507 options: JsonOptions,
508}
509
510impl<E> JsonValueBuilder<'_, '_, E>
511where
512 E: Encoding + Clone,
513{
514 pub fn with_options(mut self, options: JsonOptions) -> Self {
516 self.options = options;
517 self
518 }
519
520 pub fn to_writer<W>(self, writer: W) -> Result<(), std::io::Error>
522 where
523 W: std::io::Write,
524 {
525 writer_json(writer, self.options.pretty, &self)
526 }
527
528 pub fn to_vec(self) -> Vec<u8> {
530 let out = Vec::with_capacity(self.reader.tokens_len() * self.options.output_len_factor());
531 vec_json(out, |x| self.to_writer(x))
532 }
533
534 #[allow(clippy::inherent_to_string)]
536 pub fn to_string(self) -> String {
537 string_json(self.to_vec())
538 }
539}
540
541impl<'data, 'tokens, E> ValueReader<'data, 'tokens, E>
542where
543 E: Encoding + Clone,
544{
545 pub fn json(&self) -> JsonValueBuilder<'data, 'tokens, E> {
547 JsonValueBuilder {
548 reader: self.clone(),
549 options: JsonOptions::default(),
550 }
551 }
552}
553
554fn serialize_scalar<E, S>(reader: &ValueReader<E>, s: S) -> Result<S::Ok, S::Error>
555where
556 S: Serializer,
557 E: Encoding + Clone,
558{
559 let scalar = reader.read_scalar().unwrap();
560 if let Ok(x) = scalar.to_bool() {
561 return s.serialize_bool(x);
562 }
563
564 let signed = scalar.to_i64();
565 let unsigned = scalar.to_u64();
566 let float = scalar.to_f64();
567
568 match (signed, unsigned, float) {
571 (Ok(x), _, Ok(_)) => s.serialize_i64(x),
572 (_, Ok(x), Ok(_)) => s.serialize_u64(x),
573 (_, _, Ok(f)) => s.serialize_f64(f),
574 _ => s.serialize_str(reader.read_str().unwrap().deref()),
575 }
576}
577
578fn serialize_parameter<S>(body: &str, defined: bool, s: S) -> Result<S::Ok, S::Error>
579where
580 S: Serializer,
581{
582 let mut result = String::with_capacity(body.len() + 3);
583 result.push('[');
584
585 if !defined {
586 result.push('!');
587 }
588
589 result.push_str(body.as_ref());
590 result.push(']');
591 s.serialize_str(&result)
592}
593
594impl<E> Serialize for JsonValueBuilder<'_, '_, E>
595where
596 E: Encoding + Clone,
597{
598 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
599 where
600 S: Serializer,
601 {
602 match self.reader.token() {
603 TextToken::Unquoted(_) if self.options.type_narrowing != TypeNarrowing::None => {
604 serialize_scalar(&self.reader, serializer)
605 }
606 TextToken::Quoted(_) if self.options.type_narrowing == TypeNarrowing::All => {
607 serialize_scalar(&self.reader, serializer)
608 }
609 TextToken::Unquoted(_) | TextToken::Quoted(_) => {
610 serializer.serialize_str(self.reader.read_str().unwrap().deref())
611 }
612 TextToken::Array { .. } => {
613 let array_reader = self.reader.read_array().unwrap();
614 array_reader
615 .json()
616 .with_options(self.options)
617 .serialize(serializer)
618 }
619 TextToken::Object { .. } => {
620 let object_reader = self.reader.read_object().unwrap();
621 object_reader
622 .json()
623 .with_options(self.options)
624 .serialize(serializer)
625 }
626 TextToken::Header(_) => {
627 let arr = self.reader.read_array().unwrap();
628 let mut values = arr.values();
629 let key_reader = values.next().unwrap();
630 let value_reader = values.next().unwrap();
631
632 let mut map = serializer.serialize_map(None)?;
633 map.serialize_entry(
634 &key_reader.read_str().unwrap(),
635 &value_reader.json().with_options(self.options),
636 )?;
637 map.end()
638 }
639 TextToken::End(_)
640 | TextToken::Operator(_)
641 | TextToken::Parameter(_)
642 | TextToken::UndefinedParameter(_)
643 | TextToken::MixedContainer => serializer.serialize_none(),
644 }
645 }
646}
647
648impl<E> Serialize for JsonObjectBuilder<'_, '_, E>
649where
650 E: Encoding + Clone,
651{
652 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
653 where
654 S: Serializer,
655 {
656 match self.options.duplicate_keys {
657 DuplicateKeyMode::Group => {
658 let mut field_groups = self.reader.field_groups();
659 let mut map = serializer.serialize_map(None)?;
660
661 for (key, group) in field_groups.by_ref() {
662 match group {
663 GroupEntry::One((op, val)) => {
664 let v = OperatorValue {
665 operator: op,
666 value: val,
667 options: self.options,
668 };
669 map.serialize_entry(&KeyScalarWrapper { reader: key }, &v)?;
670 }
671 GroupEntry::Multiple(values) => {
672 let values: Vec<_> = values
673 .iter()
674 .map(|(op, val)| OperatorValue {
675 operator: *op,
676 value: val.clone(),
677 options: self.options,
678 })
679 .collect();
680 map.serialize_entry(&KeyScalarWrapper { reader: key }, &values)?;
681 }
682 }
683 }
684
685 let rest = field_groups.remainder();
686 if !rest.is_empty() {
687 map.serialize_entry(
688 "remainder",
689 &InnerSerArray {
690 reader: rest,
691 options: self.options,
692 },
693 )?;
694 }
695
696 map.end()
697 }
698 DuplicateKeyMode::Preserve => {
699 let mut map = serializer.serialize_map(None)?;
700 let mut fields = self.reader.fields();
701
702 for (key, op, val) in fields.by_ref() {
704 let v = OperatorValue {
705 operator: op,
706 value: val,
707 options: self.options,
708 };
709 map.serialize_entry(&KeyScalarWrapper { reader: key }, &v)?;
710 }
711
712 let remainder = fields.remainder();
714 if !remainder.is_empty() {
715 let is_object_like = is_key_value_pattern(&remainder);
716 if is_object_like {
717 serialize_key_value_patterns::<S, E>(&remainder, &mut map, self.options)?;
719 } else {
720 map.serialize_entry(
722 "remainder",
723 &InnerSerArray {
724 reader: remainder,
725 options: self.options,
726 },
727 )?;
728 }
729 }
730
731 map.end()
732 }
733 DuplicateKeyMode::KeyValuePairs => {
734 let mut map = serializer.serialize_map(None)?;
735 map.serialize_entry("type", "obj")?;
736 map.serialize_entry(
737 "val",
738 &SerTapeTyped {
739 reader: self.reader.clone(),
740 options: self.options,
741 },
742 )?;
743 map.end()
744 }
745 }
746 }
747}
748
749pub(crate) struct OperatorValue<'data, 'tokens, E> {
750 operator: Option<Operator>,
751 value: ValueReader<'data, 'tokens, E>,
752 options: JsonOptions,
753}
754
755impl<E> Serialize for OperatorValue<'_, '_, E>
756where
757 E: Encoding + Clone,
758{
759 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
760 where
761 S: Serializer,
762 {
763 match self.operator {
764 Some(Operator::Equal) | None => self
765 .value
766 .json()
767 .with_options(self.options)
768 .serialize(serializer),
769 Some(op) => {
770 let mut map = serializer.serialize_map(None)?;
771 let reader = &self.value;
772 map.serialize_entry(op.name(), &reader.json().with_options(self.options))?;
773 map.end()
774 }
775 }
776 }
777}
778
779pub(crate) struct InnerSerArray<'data, 'tokens, E> {
780 reader: ArrayReader<'data, 'tokens, E>,
781 options: JsonOptions,
782}
783
784impl<E> Serialize for InnerSerArray<'_, '_, E>
785where
786 E: Encoding + Clone,
787{
788 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
789 where
790 S: Serializer,
791 {
792 if is_key_value_pattern(&self.reader) {
794 let mut map = serializer.serialize_map(None)?;
796 serialize_key_value_patterns::<S, E>(&self.reader, &mut map, self.options)?;
797 return map.end();
798 }
799
800 let mut seq = serializer.serialize_seq(None)?;
801 let mut iter = self.reader.values();
802 let mut window = [iter.next(), iter.next(), iter.next()];
803
804 while let Some(first_val) = &window[0] {
805 if first_val.token() == &TextToken::MixedContainer {
806 window.swap(1, 0);
807 window.swap(2, 1);
808 window[2] = iter.next();
809 continue;
810 }
811
812 if let Some(op_reader) = &window[1] {
813 if let TextToken::Operator(op) = op_reader.token() {
814 if let Some(value) = &window[2] {
815 seq.serialize_element(&SingleObject {
816 key: first_val.clone(),
817 op: *op,
818 value: value.clone(),
819 options: self.options,
820 })?;
821
822 window = [iter.next(), iter.next(), iter.next()];
823 continue;
824 }
825 }
826 }
827
828 let v = OperatorValue {
829 operator: None,
830 value: first_val.clone(),
831 options: self.options,
832 };
833 seq.serialize_element(&v)?;
834
835 window.swap(1, 0);
836 window.swap(2, 1);
837 window[2] = iter.next();
838 }
839
840 seq.end()
841 }
842}
843
844impl<E> Serialize for JsonArrayBuilder<'_, '_, E>
845where
846 E: Encoding + Clone,
847{
848 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
849 where
850 S: Serializer,
851 {
852 let inner = InnerSerArray {
853 reader: self.reader.clone(),
854 options: self.options,
855 };
856
857 if self.options.duplicate_keys != DuplicateKeyMode::KeyValuePairs {
858 inner.serialize(serializer)
859 } else {
860 let mut map = serializer.serialize_map(None)?;
861 map.serialize_entry("type", "array")?;
862 map.serialize_entry("val", &inner)?;
863 map.end()
864 }
865 }
866}
867
868pub(crate) struct SingleObject<'data, 'tokens, E> {
869 key: ValueReader<'data, 'tokens, E>,
870 op: Operator,
871 value: ValueReader<'data, 'tokens, E>,
872 options: JsonOptions,
873}
874
875impl<E> Serialize for SingleObject<'_, '_, E>
876where
877 E: Encoding + Clone,
878{
879 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
880 where
881 S: Serializer,
882 {
883 let mut map = serializer.serialize_map(None)?;
884 let value = OperatorValue {
885 operator: Some(self.op),
886 value: self.value.clone(),
887 options: self.options,
888 };
889
890 if let Ok(x) = self.key.read_str() {
891 map.serialize_key(&x)?;
892 } else {
893 map.serialize_key("__invalid_key")?;
894 }
895
896 map.serialize_value(&value)?;
897 map.end()
898 }
899}
900
901pub(crate) struct SerTapeTyped<'data, 'tokens, E> {
902 reader: ObjectReader<'data, 'tokens, E>,
903 options: JsonOptions,
904}
905
906impl<E> Serialize for SerTapeTyped<'_, '_, E>
907where
908 E: Encoding + Clone,
909{
910 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
911 where
912 S: Serializer,
913 {
914 let mut seq = serializer.serialize_seq(None)?;
915 let mut fields = self.reader.fields();
916 for (key, op, val) in fields.by_ref() {
917 let v = OperatorValue {
918 operator: op,
919 value: val,
920 options: self.options,
921 };
922 seq.serialize_element(&(KeyScalarWrapper { reader: key }, &v))?;
923 }
924
925 let remainder = fields.remainder();
926 if !remainder.is_empty() {
927 let trailer_array = InnerSerArray {
928 reader: remainder,
929 options: self.options,
930 };
931
932 seq.serialize_element(&trailer_array)?;
933 }
934
935 seq.end()
936 }
937}
938
939pub(crate) struct KeyScalarWrapper<'data, E> {
940 reader: ScalarReader<'data, E>,
941}
942
943impl<E> Serialize for KeyScalarWrapper<'_, E>
944where
945 E: Encoding + Clone,
946{
947 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
948 where
949 S: Serializer,
950 {
951 let body = self.reader.read_str();
952 match self.reader.token() {
953 TextToken::Parameter(_) => serialize_parameter(&body, true, serializer),
954 TextToken::UndefinedParameter(_) => serialize_parameter(&body, false, serializer),
955 _ => serializer.serialize_str(&body),
956 }
957 }
958}
959
960#[cfg(test)]
961mod tests {
962 use super::*;
963 use crate::{TextTape, Windows1252Encoding};
964
965 fn serialize_with(data: &[u8], options: JsonOptions) -> String {
966 let tape = TextTape::from_slice(data).unwrap();
967 let reader = tape.windows1252_reader();
968 reader.json().with_options(options).to_string()
969 }
970
971 fn serialize(data: &[u8]) -> String {
972 serialize_with(data, JsonOptions::default())
973 }
974
975 #[test]
976 fn test_serialize_to_json() {
977 let json = serialize(b"foo=bar");
978 assert_eq!(&json, r#"{"foo":"bar"}"#);
979 }
980
981 #[test]
982 fn test_simple_types() {
983 let json = serialize(b"foo=bar num=1 bool=no bool2=yes pi=3.14");
984 let expected = r#"{"foo":"bar","num":1,"bool":false,"bool2":true,"pi":3.14}"#;
985 assert_eq!(&json, expected);
986 }
987
988 #[test]
989 fn test_object() {
990 let json = serialize(b"foo={prop=a bar={num=1}}");
991 let expected = r#"{"foo":{"prop":"a","bar":{"num":1}}}"#;
992 assert_eq!(&json, expected);
993 }
994
995 #[test]
996 fn test_array() {
997 let json = serialize(b"nums={1 2 3 4}");
998 let expected = r#"{"nums":[1,2,3,4]}"#;
999 assert_eq!(&json, expected);
1000 }
1001
1002 #[test]
1003 fn test_duplicate_fields() {
1004 let json = serialize(b"core=AAA core=BBB");
1005 let expected = r#"{"core":"AAA","core":"BBB"}"#;
1006 assert_eq!(&json, expected);
1007 }
1008
1009 #[test]
1010 fn test_duplicate_fields_grouped() {
1011 let json = serialize_with(
1012 b"core=AAA core=BBB",
1013 JsonOptions {
1014 duplicate_keys: DuplicateKeyMode::Group,
1015 ..JsonOptions::default()
1016 },
1017 );
1018 let expected = r#"{"core":["AAA","BBB"]}"#;
1019 assert_eq!(&json, expected);
1020 }
1021
1022 #[test]
1023 fn test_duplicate_fields_typed() {
1024 let json = serialize_with(
1025 b"core=AAA core=BBB",
1026 JsonOptions {
1027 duplicate_keys: DuplicateKeyMode::KeyValuePairs,
1028 ..JsonOptions::default()
1029 },
1030 );
1031 let expected = r#"{"type":"obj","val":[["core","AAA"],["core","BBB"]]}"#;
1032 assert_eq!(&json, expected);
1033 }
1034
1035 #[test]
1036 fn test_header() {
1037 let json = serialize(b"color = rgb { 100 200 150 }");
1038 let expected = r#"{"color":{"rgb":[100,200,150]}}"#;
1039 assert_eq!(&json, expected);
1040 }
1041
1042 #[test]
1043 fn test_large_numbers() {
1044 let json = serialize(b"identity = 18446744073709547616");
1045 let expected = r#"{"identity":"18446744073709547616"}"#;
1046 assert_eq!(&json, expected);
1047 }
1048
1049 #[test]
1050 fn test_large_negative_numbers() {
1051 let json = serialize(b"identity = -90071992547409097");
1052 let expected = r#"{"identity":"-90071992547409097"}"#;
1053 assert_eq!(&json, expected);
1054 }
1055
1056 #[test]
1057 fn test_object_pretty() {
1058 let json = serialize_with(
1059 b"foo={prop=a bar={num=1}}",
1060 JsonOptions {
1061 pretty: true,
1062 ..JsonOptions::default()
1063 },
1064 );
1065 let expected = r#"{
1066 "foo": {
1067 "prop": "a",
1068 "bar": {
1069 "num": 1
1070 }
1071 }
1072}"#;
1073 assert_eq!(&json, expected);
1074 }
1075
1076 #[test]
1077 fn test_array_typed() {
1078 let json = serialize_with(
1079 b"nums={1 2}",
1080 JsonOptions {
1081 duplicate_keys: DuplicateKeyMode::KeyValuePairs,
1082 ..JsonOptions::default()
1083 },
1084 );
1085 let expected = r#"{"type":"obj","val":[["nums",{"type":"array","val":[1,2]}]]}"#;
1086 assert_eq!(&json, expected);
1087 }
1088
1089 #[test]
1090 fn test_mixed_container_1() {
1091 let json = serialize(b"area = { color = { 10 } 1 2 }");
1092 let expected = r#"{"area":{"color":[10],"remainder":[1,2]}}"#;
1093 assert_eq!(&json, expected);
1094 }
1095
1096 #[test]
1097 fn test_mixed_container_2() {
1098 let json = serialize_with(
1099 b"area = { color = { 10 } 1 2 }",
1100 JsonOptions {
1101 duplicate_keys: DuplicateKeyMode::Group,
1102 ..JsonOptions::default()
1103 },
1104 );
1105 let expected = r#"{"area":{"color":[10],"remainder":[1,2]}}"#;
1106 assert_eq!(&json, expected);
1107 }
1108
1109 #[test]
1110 fn test_mixed_container_3() {
1111 let json = serialize_with(
1112 b"area = { color = { 10 } 1 2 }",
1113 JsonOptions {
1114 duplicate_keys: DuplicateKeyMode::KeyValuePairs,
1115 ..JsonOptions::default()
1116 },
1117 );
1118 let expected = r#"{"type":"obj","val":[["area",{"type":"obj","val":[["color",{"type":"array","val":[10]}],[1,2]]}]]}"#;
1119 assert_eq!(&json, expected);
1120 }
1121
1122 #[test]
1123 fn test_mixed_container_4() {
1124 let json = serialize(b"levels={ 10 0=2 1=2 }");
1125 let expected = r#"{"levels":[10,{"0":2},{"1":2}]}"#;
1126 assert_eq!(&json, expected);
1127 }
1128
1129 #[test]
1130 fn test_mixed_container_5() {
1131 let json = serialize(b"mixed={ a=b 10 c=d 20 }");
1132 let expected = r#"{"mixed":{"a":"b","remainder":[10,{"c":"d"},20]}}"#;
1133 assert_eq!(&json, expected);
1134 }
1135
1136 #[test]
1137 fn test_mixed_container_10() {
1138 let json = serialize(
1139 br"on_actions = {
1140 faith_holy_order_land_acquisition_pulse
1141 delay = { days = { 5 10 }}
1142 faith_heresy_events_pulse
1143 delay = { days = { 15 20 }}
1144 faith_fervor_events_pulse
1145 }",
1146 );
1147 let expected = r#"{"on_actions":["faith_holy_order_land_acquisition_pulse",{"delay":{"days":[5,10]}},"faith_heresy_events_pulse",{"delay":{"days":[15,20]}},"faith_fervor_events_pulse"]}"#;
1148 assert_eq!(&json, expected);
1149 }
1150
1151 #[test]
1152 fn test_parameter_definitions_typed() {
1153 let json = serialize_with(
1154 b"generate_advisor = { [[scaled_skill] a=b ] [[!scaled_skill] c=d ] }",
1155 JsonOptions {
1156 duplicate_keys: DuplicateKeyMode::KeyValuePairs,
1157 ..JsonOptions::default()
1158 },
1159 );
1160 let expected = r#"{"type":"obj","val":[["generate_advisor",{"type":"obj","val":[["[scaled_skill]",{"type":"obj","val":[["a","b"]]}],["[!scaled_skill]",{"type":"obj","val":[["c","d"]]}]]}]]}"#;
1161 assert_eq!(&json, expected);
1162 }
1163
1164 #[test]
1165 fn test_parameter_definition_value_typed() {
1166 let json = serialize_with(
1167 b"foo = { [[add] $add$]}",
1168 JsonOptions {
1169 duplicate_keys: DuplicateKeyMode::KeyValuePairs,
1170 ..JsonOptions::default()
1171 },
1172 );
1173 let expected = r#"{"type":"obj","val":[["foo",{"type":"obj","val":[["[add]","$add$"]]}]]}"#;
1174 assert_eq!(&json, expected);
1175 }
1176
1177 #[test]
1178 fn test_subobject() {
1179 let tape = TextTape::from_slice(b"bar={num=1}").unwrap();
1180 let reader = tape.windows1252_reader();
1181 let mut fields = reader.fields();
1182 let (_key, _op, value) = fields.next().unwrap();
1183 let actual = value.json().to_string();
1184 let expected = r#"{"num":1}"#;
1185 assert_eq!(&actual, expected);
1186 }
1187
1188 #[test]
1189 fn test_array_direct() {
1190 let tape = TextTape::from_slice(b"nums={1 2 3 4}").unwrap();
1191 let reader = tape.windows1252_reader();
1192 let mut fields = reader.fields();
1193 let (_key, _op, value) = fields.next().unwrap();
1194 let array = value.read_array().unwrap();
1195 let actual = array.json().to_string();
1196 let expected = r#"[1,2,3,4]"#;
1197 assert_eq!(&actual, expected);
1198 }
1199
1200 #[test]
1201 fn test_value_direct() {
1202 let tape = TextTape::from_slice(b"core=1").unwrap();
1203 let reader = tape.windows1252_reader();
1204 let mut fields = reader.fields();
1205 let (_key, _op, value) = fields.next().unwrap();
1206 let actual = value.json().to_string();
1207 let expected = r#"1"#;
1208 assert_eq!(&actual, expected);
1209 }
1210
1211 #[test]
1212 fn test_builder_serialization() {
1213 #[derive(Serialize)]
1214 struct MyStruct<'a, 'b> {
1215 bar: JsonValueBuilder<'a, 'b, Windows1252Encoding>,
1216 qux: JsonValueBuilder<'a, 'b, Windows1252Encoding>,
1217 }
1218
1219 let tape = TextTape::from_slice(b"bar={num=1} qux={num=2}").unwrap();
1220 let reader = tape.windows1252_reader();
1221 let mut fields = reader.fields();
1222 let (_key, _op, value) = fields.next().unwrap();
1223 let bar = value.json();
1224
1225 let (_key, _op, value) = fields.next().unwrap();
1226 let qux = value.json();
1227
1228 let actual = serde_json::to_string(&MyStruct { bar, qux }).unwrap();
1229 let expected = r#"{"bar":{"num":1},"qux":{"num":2}}"#;
1230 assert_eq!(&actual, expected);
1231 }
1232
1233 #[test]
1234 fn test_object_template_basic() {
1235 let json = serialize(b"obj={ { a = b }={ 1 2 3 } }");
1236 let expected = r#"{"obj":[{"a":"b"},[1,2,3]]}"#;
1237 assert_eq!(&json, expected);
1238 }
1239
1240 #[test]
1241 fn test_object_template_single_value() {
1242 let json = serialize(b"obj={ { foo }={ 1000 } }");
1243 let expected = r#"{"obj":[["foo"],[1000]]}"#;
1244 assert_eq!(&json, expected);
1245 }
1246
1247 #[test]
1248 fn test_object_template_sequential() {
1249 let json = serialize(b"obj={ { template1 }={ values1 } { template2 }={ values2 } }");
1250 let expected = r#"{"obj":[["template1"],["values1"],["template2"],["values2"]]}"#;
1251 assert_eq!(&json, expected);
1252 }
1253
1254 #[test]
1255 fn test_object_template_with_preserve_duplicates() {
1256 let json = serialize_with(
1257 b"obj={ { a = b }={ 1 2 3 } }",
1258 JsonOptions {
1259 duplicate_keys: DuplicateKeyMode::Preserve,
1260 ..JsonOptions::default()
1261 },
1262 );
1263 let expected = r#"{"obj":[{"a":"b"},[1,2,3]]}"#;
1264 assert_eq!(&json, expected);
1265 }
1266
1267 #[test]
1268 fn test_object_template_with_key_value_pairs() {
1269 let json = serialize_with(
1270 b"obj={ { a = b }={ 1 2 3 } }",
1271 JsonOptions {
1272 duplicate_keys: DuplicateKeyMode::KeyValuePairs,
1273 ..JsonOptions::default()
1274 },
1275 );
1276 let expected = r#"{"type":"obj","val":[["obj",{"type":"array","val":[{"type":"obj","val":[["a","b"]]},{"type":"array","val":[1,2,3]}]}]]}"#;
1277 assert_eq!(&json, expected);
1278 }
1279
1280 #[test]
1281 fn test_object_template_complex() {
1282 let json = serialize(
1283 b"config={ { debug=yes logging=verbose }={ output_file=\"debug.log\" level=trace } }",
1284 );
1285 let expected = r#"{"config":[{"debug":true,"logging":"verbose"},{"output_file":"debug.log","level":"trace"}]}"#;
1286 assert_eq!(&json, expected);
1287 }
1288
1289 #[test]
1290 fn test_object_template_nested() {
1291 let json = serialize(b"obj={ { outer }={ { inner }={ deep } } }");
1292 let expected = r#"{"obj":[["outer"],[["inner"],["deep"]]]}"#;
1293 assert_eq!(&json, expected);
1294 }
1295
1296 #[test]
1297 fn test_object_template_pretty() {
1298 let json = serialize_with(
1299 b"obj={ { a = b }={ 1 2 3 } }",
1300 JsonOptions {
1301 pretty: true,
1302 ..JsonOptions::default()
1303 },
1304 );
1305 let expected = r#"{
1306 "obj": [
1307 {
1308 "a": "b"
1309 },
1310 [
1311 1,
1312 2,
1313 3
1314 ]
1315 ]
1316}"#;
1317 assert_eq!(&json, expected);
1318 }
1319
1320 #[test]
1321 fn test_object_template_scalar_value() {
1322 let json = serialize(b"obj={ { 31=16 }=16 }");
1323 let expected = r#"{"obj":[{"31":16},16]}"#;
1324 assert_eq!(&json, expected);
1325 }
1326
1327 #[test]
1328 fn test_equals_operator_mutation() {
1329 use crate::text::{Operator, TextToken};
1330
1331 let mut tape = TextTape::from_slice(b"foo ?= 10").unwrap();
1333
1334 let reader_before = tape.windows1252_reader();
1336 let json_before = reader_before.json().to_string();
1337 let expected_before = r#"{"foo":{"EXISTS":10}}"#;
1338 assert_eq!(&json_before, expected_before);
1339
1340 let tokens = tape.tokens_mut();
1342 for token in tokens.iter_mut() {
1343 if let TextToken::Operator(Operator::Exists) = token {
1344 *token = TextToken::Operator(Operator::Equal);
1345 break;
1346 }
1347 }
1348
1349 let reader_after = tape.windows1252_reader();
1351 let json_after = reader_after.json().to_string();
1352 let expected_after = r#"{"foo":10}"#;
1353 assert_eq!(&json_after, expected_after);
1354 }
1355
1356 #[test]
1357 fn test_mixed_array_remains_array() {
1358 let json = serialize(b"test={ a=1 standalone b=2 }");
1360 assert_eq!(
1361 &json,
1362 "{\"test\":{\"a\":1,\"remainder\":[\"standalone\",{\"b\":2}]}}"
1363 );
1364 }
1365
1366 #[test]
1367 fn test_empty_containers() {
1368 let json = serialize(b"empty={}");
1369 assert_eq!(&json, "{\"empty\":[]}");
1370 }
1371
1372 #[test]
1373 fn test_single_key_value_pair() {
1374 let json = serialize(b"single={ key=value }");
1375 assert_eq!(&json, "{\"single\":{\"key\":\"value\"}}");
1376 }
1377
1378 #[test]
1379 fn test_operators_other_than_equal() {
1380 let json = serialize(b"test={ a>1 b<2 c>=3 d<=4 e!=5 }");
1382 assert_eq!(&json, "{\"test\":{\"a\":{\"GREATER_THAN\":1},\"b\":{\"LESS_THAN\":2},\"c\":{\"GREATER_THAN_EQUAL\":3},\"d\":{\"LESS_THAN_EQUAL\":4},\"e\":{\"NOT_EQUAL\":5}}}");
1383 }
1384
1385 #[test]
1386 fn test_complex_nested_structures() {
1387 let json =
1388 serialize(b"complex={ nested={ a=1 b=2 } standalone={ c=3 } mixed={ d=4 bare e=5 } }");
1389 assert_eq!(&json, "{\"complex\":{\"nested\":{\"a\":1,\"b\":2},\"standalone\":{\"c\":3},\"mixed\":{\"d\":4,\"remainder\":[\"bare\",{\"e\":5}]}}}");
1390 }
1391
1392 #[test]
1393 fn test_stress_alternating_patterns() {
1394 let json = serialize(b"test={ a=1 standalone1 b=2 standalone2 c=3 }");
1395 assert_eq!(&json, "{\"test\":{\"a\":1,\"remainder\":[\"standalone1\",{\"b\":2},\"standalone2\",{\"c\":3}]}}");
1396 }
1397
1398 #[test]
1399 fn test_preserve_vs_group_mode_consistency() {
1400 let data = b"test={ scope:treaty != this scope:county = yes }";
1401
1402 let preserve_json = serialize_with(data, JsonOptions::new());
1403 let group_json = serialize_with(
1404 data,
1405 JsonOptions::new().with_duplicate_keys(DuplicateKeyMode::Group),
1406 );
1407 assert_eq!(
1408 preserve_json,
1409 "{\"test\":{\"scope:treaty\":{\"NOT_EQUAL\":\"this\"},\"scope:county\":true}}"
1410 );
1411 assert_eq!(
1412 group_json,
1413 "{\"test\":{\"scope:treaty\":{\"NOT_EQUAL\":\"this\"},\"scope:county\":true}}"
1414 );
1415 }
1416
1417 #[test]
1418 fn test_field_order_encoding_consistency() {
1419 let a_trigger = br#"a_trigger = {
1420 OR = {
1421 obj_a = {
1422 a_bool = no
1423 }
1424 obj_a.field != this
1425 }
1426}"#;
1427
1428 let b_trigger = br#"b_trigger = {
1429 OR = {
1430 obj_a.field != this
1431 obj_a = {
1432 a_bool = no
1433 }
1434 }
1435}"#;
1436
1437 let a_json = serialize(a_trigger);
1438 let b_json = serialize(b_trigger);
1439
1440 assert_eq!(
1441 a_json,
1442 "{\"a_trigger\":{\"OR\":{\"obj_a\":{\"a_bool\":false},\"obj_a.field\":{\"NOT_EQUAL\":\"this\"}}}}"
1443 );
1444 assert_eq!(
1445 b_json,
1446 "{\"b_trigger\":{\"OR\":{\"obj_a.field\":{\"NOT_EQUAL\":\"this\"},\"obj_a\":{\"a_bool\":false}}}}"
1447 );
1448 }
1449}