1use crate::{DomainError, DomainResult};
7use serde::de::{
8 Deserialize, DeserializeSeed, Deserializer, Error as DeError, MapAccess, SeqAccess, Visitor,
9};
10use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer};
11use std::collections::HashMap;
12use std::fmt;
13
14#[derive(Debug, Clone, PartialEq, Default)]
17#[non_exhaustive]
18pub enum JsonData {
19 #[default]
20 Null,
22 Bool(bool),
24 Integer(i64),
26 Float(f64),
28 String(String),
30 Array(Vec<JsonData>),
32 Object(HashMap<String, JsonData>),
34}
35
36impl JsonData {
37 pub fn null() -> Self {
39 Self::Null
40 }
41
42 pub fn bool(value: bool) -> Self {
44 Self::Bool(value)
45 }
46
47 pub fn integer(value: i64) -> Self {
49 Self::Integer(value)
50 }
51
52 pub fn float(value: f64) -> DomainResult<Self> {
68 if value.is_nan() || value.is_infinite() {
69 return Err(DomainError::InvalidInput(
70 "JSON does not support NaN or infinite float values (RFC 8259 §6)".to_string(),
71 ));
72 }
73 Ok(Self::Float(value))
74 }
75
76 pub fn string<S: Into<String>>(value: S) -> Self {
78 Self::String(value.into())
79 }
80
81 pub fn array(values: Vec<JsonData>) -> Self {
83 Self::Array(values)
84 }
85
86 pub fn object(values: HashMap<String, JsonData>) -> Self {
88 Self::Object(values)
89 }
90
91 pub fn is_null(&self) -> bool {
93 matches!(self, Self::Null)
94 }
95
96 pub fn is_bool(&self) -> bool {
98 matches!(self, Self::Bool(_))
99 }
100
101 pub fn is_integer(&self) -> bool {
103 matches!(self, Self::Integer(_))
104 }
105
106 pub fn is_float(&self) -> bool {
108 matches!(self, Self::Float(_))
109 }
110
111 pub fn is_number(&self) -> bool {
113 matches!(self, Self::Integer(_) | Self::Float(_))
114 }
115
116 pub fn is_string(&self) -> bool {
118 matches!(self, Self::String(_))
119 }
120
121 pub fn is_array(&self) -> bool {
123 matches!(self, Self::Array(_))
124 }
125
126 pub fn is_object(&self) -> bool {
128 matches!(self, Self::Object(_))
129 }
130
131 pub fn as_bool(&self) -> Option<bool> {
133 match self {
134 Self::Bool(b) => Some(*b),
135 _ => None,
136 }
137 }
138
139 pub fn as_i64(&self) -> Option<i64> {
141 match self {
142 Self::Integer(i) => Some(*i),
143 _ => None,
144 }
145 }
146
147 pub fn as_f64(&self) -> Option<f64> {
149 match self {
150 Self::Float(f) => Some(*f),
151 Self::Integer(i) => Some(*i as f64),
152 _ => None,
153 }
154 }
155
156 pub fn as_str(&self) -> Option<&str> {
158 match self {
159 Self::String(s) => Some(s),
160 _ => None,
161 }
162 }
163
164 pub fn as_array(&self) -> Option<&Vec<JsonData>> {
166 match self {
167 Self::Array(arr) => Some(arr),
168 _ => None,
169 }
170 }
171
172 pub fn as_array_mut(&mut self) -> Option<&mut Vec<JsonData>> {
174 match self {
175 Self::Array(arr) => Some(arr),
176 _ => None,
177 }
178 }
179
180 pub fn as_object(&self) -> Option<&HashMap<String, JsonData>> {
182 match self {
183 Self::Object(obj) => Some(obj),
184 _ => None,
185 }
186 }
187
188 pub fn as_object_mut(&mut self) -> Option<&mut HashMap<String, JsonData>> {
190 match self {
191 Self::Object(obj) => Some(obj),
192 _ => None,
193 }
194 }
195
196 pub fn get(&self, key: &str) -> Option<&JsonData> {
198 match self {
199 Self::Object(obj) => obj.get(key),
200 _ => None,
201 }
202 }
203
204 pub fn path(&self, path: &str) -> Option<&JsonData> {
206 let parts: Vec<&str> = path.split('.').collect();
207 let mut current = self;
208
209 for part in parts {
210 match current {
211 Self::Object(obj) => {
212 current = obj.get(part)?;
213 }
214 _ => return None,
215 }
216 }
217
218 Some(current)
219 }
220
221 pub fn set_path(&mut self, path: &str, value: JsonData) -> bool {
223 let parts: Vec<&str> = path.split('.').collect();
224 if parts.is_empty() {
225 return false;
226 }
227
228 if parts.len() == 1 {
229 if let Self::Object(obj) = self {
230 obj.insert(parts[0].to_string(), value);
231 return true;
232 }
233 return false;
234 }
235
236 let mut current = self;
238 for part in &parts[..parts.len() - 1] {
239 match current {
240 Self::Object(obj) => {
241 if !obj.contains_key(*part) {
242 obj.insert(part.to_string(), Self::object(HashMap::new()));
243 }
244 current = obj
245 .get_mut(*part)
246 .expect("Key must exist as we just inserted it above");
247 }
248 _ => return false,
249 }
250 }
251
252 if let Self::Object(obj) = current {
254 obj.insert(parts[parts.len() - 1].to_string(), value);
255 true
256 } else {
257 false
258 }
259 }
260
261 pub fn memory_size(&self) -> usize {
263 match self {
264 Self::Null => 1,
265 Self::Bool(_) => 1,
266 Self::Integer(_) => 8,
267 Self::Float(_) => 8,
268 Self::String(s) => s.len() * 2, Self::Array(arr) => 8 + arr.iter().map(|v| v.memory_size()).sum::<usize>(),
270 Self::Object(obj) => {
271 16 + obj
272 .iter()
273 .map(|(k, v)| k.len() * 2 + v.memory_size())
274 .sum::<usize>()
275 }
276 }
277 }
278}
279
280impl fmt::Display for JsonData {
281 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
282 match self {
283 Self::Null => write!(f, "null"),
284 Self::Bool(b) => write!(f, "{b}"),
285 Self::Integer(i) => write!(f, "{i}"),
286 Self::Float(float_val) => write!(f, "{float_val}"),
287 Self::String(s) => write!(f, "\"{s}\""),
288 Self::Array(arr) => {
289 write!(f, "[")?;
290 for (i, item) in arr.iter().enumerate() {
291 if i > 0 {
292 write!(f, ",")?;
293 }
294 write!(f, "{item}")?;
295 }
296 write!(f, "]")
297 }
298 Self::Object(obj) => {
299 write!(f, "{{")?;
300 for (i, (key, value)) in obj.iter().enumerate() {
301 if i > 0 {
302 write!(f, ",")?;
303 }
304 write!(f, "\"{key}\":{value}")?;
305 }
306 write!(f, "}}")
307 }
308 }
309 }
310}
311
312impl Eq for JsonData {}
313
314impl std::hash::Hash for JsonData {
315 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
316 match self {
317 Self::Null => 0u8.hash(state),
318 Self::Bool(b) => {
319 1u8.hash(state);
320 b.hash(state);
321 }
322 Self::Integer(i) => {
323 2u8.hash(state);
324 i.hash(state);
325 }
326 Self::Float(f) => {
327 3u8.hash(state);
328 f.to_bits().hash(state);
330 }
331 Self::String(s) => {
332 4u8.hash(state);
333 s.hash(state);
334 }
335 Self::Array(arr) => {
336 5u8.hash(state);
337 arr.hash(state);
338 }
339 Self::Object(obj) => {
340 6u8.hash(state);
341 let mut pairs: Vec<_> = obj.iter().collect();
344 pairs.sort_by_key(|(k, _)| *k);
345 pairs.hash(state);
346 }
347 }
348 }
349}
350
351impl From<bool> for JsonData {
352 fn from(value: bool) -> Self {
353 Self::Bool(value)
354 }
355}
356
357impl From<i64> for JsonData {
358 fn from(value: i64) -> Self {
359 Self::Integer(value)
360 }
361}
362
363impl From<String> for JsonData {
364 fn from(value: String) -> Self {
365 Self::String(value)
366 }
367}
368
369impl From<&str> for JsonData {
370 fn from(value: &str) -> Self {
371 Self::String(value.to_string())
372 }
373}
374
375impl From<Vec<JsonData>> for JsonData {
376 fn from(value: Vec<JsonData>) -> Self {
377 Self::Array(value)
378 }
379}
380
381impl From<HashMap<String, JsonData>> for JsonData {
382 fn from(value: HashMap<String, JsonData>) -> Self {
383 Self::Object(value)
384 }
385}
386
387impl From<serde_json::Value> for JsonData {
388 fn from(value: serde_json::Value) -> Self {
389 match value {
390 serde_json::Value::Null => Self::Null,
391 serde_json::Value::Bool(b) => Self::Bool(b),
392 serde_json::Value::Number(n) => {
393 if let Some(i) = n.as_i64() {
394 Self::Integer(i)
395 } else if let Some(f) = n.as_f64() {
396 Self::Float(f)
397 } else {
398 Self::Float(0.0) }
400 }
401 serde_json::Value::String(s) => Self::String(s),
402 serde_json::Value::Array(arr) => {
403 let converted: Vec<JsonData> = arr.into_iter().map(JsonData::from).collect();
404 Self::Array(converted)
405 }
406 serde_json::Value::Object(obj) => {
407 let converted: HashMap<String, JsonData> = obj
408 .into_iter()
409 .map(|(k, v)| (k, JsonData::from(v)))
410 .collect();
411 Self::Object(converted)
412 }
413 }
414 }
415}
416
417impl Serialize for JsonData {
435 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
436 where
437 S: Serializer,
438 {
439 match self {
440 JsonData::Null => serializer.serialize_unit(),
441 JsonData::Bool(b) => serializer.serialize_bool(*b),
442 JsonData::Integer(i) => serializer.serialize_i64(*i),
443 JsonData::Float(f) => serializer.serialize_f64(*f),
444 JsonData::String(s) => serializer.serialize_str(s),
445 JsonData::Array(arr) => {
446 let mut seq = serializer.serialize_seq(Some(arr.len()))?;
447 for item in arr {
448 seq.serialize_element(item)?;
449 }
450 seq.end()
451 }
452 JsonData::Object(obj) => {
453 let mut map = serializer.serialize_map(Some(obj.len()))?;
454 for (key, value) in obj {
455 map.serialize_entry(key, value)?;
456 }
457 map.end()
458 }
459 }
460 }
461}
462
463impl<'de> Deserialize<'de> for JsonData {
482 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
483 where
484 D: Deserializer<'de>,
485 {
486 deserializer.deserialize_any(JsonDataVisitor { depth: 0 })
487 }
488}
489
490pub const MAX_DESERIALIZE_DEPTH: usize = 64;
518
519struct JsonDataSeed {
525 depth: usize,
526}
527
528impl<'de> DeserializeSeed<'de> for JsonDataSeed {
529 type Value = JsonData;
530
531 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
532 where
533 D: Deserializer<'de>,
534 {
535 deserializer.deserialize_any(JsonDataVisitor { depth: self.depth })
536 }
537}
538
539const MAX_PREALLOC_BYTES: usize = 1024 * 1024;
558
559fn cautious_capacity<Element>(hint: Option<usize>) -> usize {
567 match hint {
568 Some(hint) => hint.min(MAX_PREALLOC_BYTES / size_of::<Element>().max(1)),
569 None => 0,
570 }
571}
572
573struct JsonDataVisitor {
574 depth: usize,
575}
576
577impl JsonDataVisitor {
578 fn enter<E: DeError>(&self) -> Result<JsonDataSeed, E> {
580 if self.depth >= MAX_DESERIALIZE_DEPTH {
581 return Err(E::custom(format_args!(
582 "JSON nesting depth exceeds maximum of {MAX_DESERIALIZE_DEPTH}"
583 )));
584 }
585 Ok(JsonDataSeed {
586 depth: self.depth + 1,
587 })
588 }
589}
590
591impl<'de> Visitor<'de> for JsonDataVisitor {
592 type Value = JsonData;
593
594 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
595 formatter.write_str("a valid JSON value")
596 }
597
598 fn visit_unit<E>(self) -> Result<Self::Value, E> {
599 Ok(JsonData::Null)
600 }
601
602 fn visit_none<E>(self) -> Result<Self::Value, E> {
603 Ok(JsonData::Null)
604 }
605
606 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
614 where
615 D: Deserializer<'de>,
616 {
617 deserializer.deserialize_any(self)
618 }
619
620 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E> {
621 Ok(JsonData::Bool(v))
622 }
623
624 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E> {
625 Ok(JsonData::Integer(v))
626 }
627
628 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> {
629 match i64::try_from(v) {
630 Ok(i) => Ok(JsonData::Integer(i)),
631 Err(_) => Ok(JsonData::Float(v as f64)),
632 }
633 }
634
635 fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
636 where
637 E: DeError,
638 {
639 if v.is_nan() || v.is_infinite() {
640 return Err(E::custom(
641 "JSON does not support NaN or infinite float values (RFC 8259 §6)",
642 ));
643 }
644 Ok(JsonData::Float(v))
645 }
646
647 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> {
648 Ok(JsonData::String(v.to_owned()))
649 }
650
651 fn visit_string<E>(self, v: String) -> Result<Self::Value, E> {
652 Ok(JsonData::String(v))
653 }
654
655 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
656 where
657 A: SeqAccess<'de>,
658 {
659 let seed = self.enter()?;
660 let mut vec = Vec::with_capacity(cautious_capacity::<JsonData>(seq.size_hint()));
661 while let Some(elem) = seq.next_element_seed(JsonDataSeed { depth: seed.depth })? {
662 vec.push(elem);
663 }
664 Ok(JsonData::Array(vec))
665 }
666
667 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
668 where
669 A: MapAccess<'de>,
670 {
671 let seed = self.enter()?;
672 let mut obj =
673 HashMap::with_capacity(cautious_capacity::<(String, JsonData)>(map.size_hint()));
674 while let Some(key) = map.next_key::<String>()? {
677 let value = map.next_value_seed(JsonDataSeed { depth: seed.depth })?;
678 obj.insert(key, value);
679 }
680 Ok(JsonData::Object(obj))
681 }
682}
683
684#[cfg(test)]
685mod tests {
686 use super::*;
687
688 #[test]
689 fn test_json_data_creation() {
690 assert_eq!(JsonData::null(), JsonData::Null);
691 assert_eq!(JsonData::bool(true), JsonData::Bool(true));
692 assert_eq!(JsonData::float(42.0).unwrap(), JsonData::Float(42.0));
693 assert_eq!(
694 JsonData::string("hello"),
695 JsonData::String("hello".to_string())
696 );
697 }
698
699 #[test]
700 fn test_json_data_type_checks() {
701 assert!(JsonData::null().is_null());
702 assert!(JsonData::bool(true).is_bool());
703 assert!(JsonData::float(42.0).unwrap().is_number());
704 assert!(JsonData::string("hello").is_string());
705 assert!(JsonData::array(vec![]).is_array());
706 assert!(JsonData::object(HashMap::new()).is_object());
707 }
708
709 #[test]
710 fn test_json_data_conversions() {
711 assert_eq!(JsonData::bool(true).as_bool(), Some(true));
712 assert_eq!(JsonData::float(42.0).unwrap().as_f64(), Some(42.0));
713 assert_eq!(JsonData::integer(42).as_i64(), Some(42));
714 assert_eq!(JsonData::string("hello").as_str(), Some("hello"));
715 }
716
717 #[test]
718 fn test_path_operations() {
719 let mut data = JsonData::object(HashMap::new());
720
721 assert!(data.set_path("user.name", JsonData::string("John")));
723 assert!(data.set_path("user.age", JsonData::integer(30)));
724
725 assert_eq!(data.path("user.name").unwrap().as_str(), Some("John"));
727 assert_eq!(data.path("user.age").unwrap().as_i64(), Some(30));
728
729 assert!(data.path("user.email").is_none());
731 }
732
733 #[test]
734 fn test_memory_size() {
735 let data = JsonData::object(
736 [
737 ("name".to_string(), JsonData::string("John")),
738 ("age".to_string(), JsonData::integer(30)),
739 ]
740 .into_iter()
741 .collect(),
742 );
743
744 assert!(data.memory_size() > 0);
745 }
746
747 #[test]
748 fn test_display() {
749 let data = JsonData::object(
750 [
751 ("name".to_string(), JsonData::string("John")),
752 ("active".to_string(), JsonData::bool(true)),
753 ]
754 .into_iter()
755 .collect(),
756 );
757
758 let display = format!("{data}");
759 assert!(display.contains("name"));
760 assert!(display.contains("John"));
761 }
762
763 #[test]
764 fn test_deserialize_rejects_nan_float() {
765 use serde::de::IntoDeserializer;
766 let deserializer: serde::de::value::F64Deserializer<serde::de::value::Error> =
767 f64::NAN.into_deserializer();
768 let result: Result<JsonData, _> = JsonData::deserialize(deserializer);
769 assert!(result.is_err());
770 }
771
772 #[test]
773 fn test_deserialize_rejects_infinite_float() {
774 use serde::de::IntoDeserializer;
775 let deserializer: serde::de::value::F64Deserializer<serde::de::value::Error> =
776 f64::INFINITY.into_deserializer();
777 let result: Result<JsonData, _> = JsonData::deserialize(deserializer);
778 assert!(result.is_err());
779 }
780
781 #[test]
782 fn test_deserialize_malformed_json_errors() {
783 let result: Result<JsonData, _> = serde_json::from_str("{not valid json");
784 assert!(result.is_err());
785 }
786
787 #[test]
788 fn test_deserialize_large_u64_becomes_float() {
789 let data: JsonData = serde_json::from_str(&u64::MAX.to_string()).unwrap();
790 assert!(matches!(data, JsonData::Float(_)));
791 }
792
793 #[test]
794 fn test_deserialize_unicode_string_roundtrip() {
795 let original = JsonData::string("Hello, 世界 🦀");
796 let json = serde_json::to_string(&original).unwrap();
797 let back: JsonData = serde_json::from_str(&json).unwrap();
798 assert_eq!(original, back);
799 }
800
801 #[test]
802 fn test_deserialize_deeply_nested_roundtrip() {
803 let mut data = JsonData::string("leaf");
804 for _ in 0..64 {
805 data = JsonData::array(vec![data]);
806 }
807 let json = serde_json::to_string(&data).unwrap();
808 let back: JsonData = serde_json::from_str(&json).unwrap();
809 assert_eq!(data, back);
810 }
811
812 #[test]
813 fn test_cautious_capacity_bounds_hostile_size_hint() {
814 let capped = cautious_capacity::<JsonData>(Some(usize::MAX));
818 assert!(capped * size_of::<JsonData>() <= MAX_PREALLOC_BYTES);
819
820 let capped_pair = cautious_capacity::<(String, JsonData)>(Some(usize::MAX));
821 assert!(capped_pair * size_of::<(String, JsonData)>() <= MAX_PREALLOC_BYTES);
822
823 assert_eq!(cautious_capacity::<JsonData>(Some(3)), 3);
825 assert_eq!(cautious_capacity::<JsonData>(None), 0);
826 }
827
828 #[test]
829 fn test_cautious_capacity_bounds_mid_range_hostile_size_hint() {
830 let hint = 100_000_000;
836 let capped = cautious_capacity::<JsonData>(Some(hint));
837 assert!(capped < hint);
838 assert!(capped * size_of::<JsonData>() <= MAX_PREALLOC_BYTES);
839 }
840
841 struct HostileSeqAccess {
846 remaining: usize,
847 }
848
849 impl<'de> SeqAccess<'de> for HostileSeqAccess {
850 type Error = serde_json::Error;
851
852 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
853 where
854 T: serde::de::DeserializeSeed<'de>,
855 {
856 if self.remaining == 0 {
857 return Ok(None);
858 }
859 self.remaining -= 1;
860 seed.deserialize(serde_json::Value::Null).map(Some)
861 }
862
863 fn size_hint(&self) -> Option<usize> {
864 Some(usize::MAX)
865 }
866 }
867
868 struct HostileSeqDeserializer;
869
870 impl<'de> Deserializer<'de> for HostileSeqDeserializer {
871 type Error = serde_json::Error;
872
873 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
874 where
875 V: Visitor<'de>,
876 {
877 visitor.visit_seq(HostileSeqAccess { remaining: 3 })
878 }
879
880 serde::forward_to_deserialize_any! {
881 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
882 bytes byte_buf option unit unit_struct newtype_struct seq tuple
883 tuple_struct map struct enum identifier ignored_any
884 }
885 }
886
887 #[test]
888 fn test_visit_seq_ignores_hostile_size_hint() {
889 let result: JsonData = JsonData::deserialize(HostileSeqDeserializer).unwrap();
895 assert_eq!(
896 result,
897 JsonData::Array(vec![JsonData::Null, JsonData::Null, JsonData::Null])
898 );
899 }
900
901 struct HostileMapAccess {
903 remaining: usize,
904 }
905
906 impl<'de> MapAccess<'de> for HostileMapAccess {
907 type Error = serde_json::Error;
908
909 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
910 where
911 K: serde::de::DeserializeSeed<'de>,
912 {
913 if self.remaining == 0 {
914 return Ok(None);
915 }
916 self.remaining -= 1;
917 seed.deserialize(serde_json::Value::String(format!("k{}", self.remaining)))
918 .map(Some)
919 }
920
921 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
922 where
923 V: serde::de::DeserializeSeed<'de>,
924 {
925 seed.deserialize(serde_json::Value::Null)
926 }
927
928 fn size_hint(&self) -> Option<usize> {
929 Some(usize::MAX)
930 }
931 }
932
933 struct HostileMapDeserializer;
934
935 impl<'de> Deserializer<'de> for HostileMapDeserializer {
936 type Error = serde_json::Error;
937
938 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
939 where
940 V: Visitor<'de>,
941 {
942 visitor.visit_map(HostileMapAccess { remaining: 2 })
943 }
944
945 serde::forward_to_deserialize_any! {
946 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
947 bytes byte_buf option unit unit_struct newtype_struct seq tuple
948 tuple_struct map struct enum identifier ignored_any
949 }
950 }
951
952 #[test]
953 fn test_visit_map_ignores_hostile_size_hint() {
954 let result: JsonData = JsonData::deserialize(HostileMapDeserializer).unwrap();
955 assert!(result.is_object());
956 assert_eq!(result.as_object().unwrap().len(), 2);
957 }
958
959 #[test]
960 fn test_serde_json_to_value_roundtrip_primitives() {
961 let data = JsonData::string("hello");
962 let value = serde_json::to_value(&data).unwrap();
963 let back = JsonData::from(value);
964 assert_eq!(data, back);
965 }
966
967 #[test]
968 fn test_serde_json_to_value_roundtrip_complex() {
969 let data = JsonData::object(
970 [
971 ("name".to_string(), JsonData::string("John")),
972 ("age".to_string(), JsonData::integer(30)),
973 ("active".to_string(), JsonData::bool(true)),
974 ]
975 .into_iter()
976 .collect(),
977 );
978
979 let value = serde_json::to_value(&data).unwrap();
980 let back = JsonData::from(value);
981 assert_eq!(data, back);
982 }
983
984 #[test]
985 fn test_non_finite_float_serializes_as_json_null() {
986 for non_finite in [f64::NAN, f64::INFINITY, f64::NEG_INFINITY] {
992 let data = JsonData::Float(non_finite);
993 let value = serde_json::to_value(&data).unwrap();
994 assert_eq!(value, serde_json::Value::Null);
995 }
996 }
997
998 fn nested_msgpack(levels: usize) -> Vec<u8> {
1000 let mut buf = vec![0x91u8; levels];
1001 buf.push(0xc0);
1002 buf
1003 }
1004
1005 #[test]
1006 fn test_deserialize_msgpack_at_max_depth_succeeds() {
1007 let data: Result<JsonData, _> =
1008 rmp_serde::from_slice(&nested_msgpack(MAX_DESERIALIZE_DEPTH));
1009 assert!(data.is_ok(), "{:?}", data.err());
1010 }
1011
1012 #[test]
1013 fn test_deserialize_msgpack_beyond_max_depth_rejected() {
1014 let err = rmp_serde::from_slice::<JsonData>(&nested_msgpack(MAX_DESERIALIZE_DEPTH + 1))
1015 .unwrap_err()
1016 .to_string();
1017 assert!(err.contains("nesting depth"), "{err}");
1020 }
1021
1022 #[test]
1023 fn test_deserialize_json_beyond_max_depth_rejected() {
1024 let levels = MAX_DESERIALIZE_DEPTH + 1;
1025 let json = format!("{}1{}", "[".repeat(levels), "]".repeat(levels));
1026 let err = serde_json::from_str::<JsonData>(&json)
1027 .unwrap_err()
1028 .to_string();
1029 assert!(err.contains("nesting depth"), "{err}");
1030 }
1031
1032 #[test]
1045 fn test_deserialize_extreme_nesting_does_not_overflow_stack() {
1046 let payload = nested_msgpack(100_000);
1047 let err = std::thread::Builder::new()
1048 .stack_size(2 * 1024 * 1024)
1049 .spawn(move || {
1050 rmp_serde::from_slice::<JsonData>(&payload)
1051 .unwrap_err()
1052 .to_string()
1053 })
1054 .expect("thread spawn")
1055 .join()
1056 .expect("worker must return an error, not overflow the stack");
1057 assert!(err.contains("nesting depth"), "{err}");
1058 }
1059
1060 #[test]
1063 fn test_deserialize_nested_large_size_hints_rejected_at_depth() {
1064 let mut buf = Vec::new();
1065 for _ in 0..200 {
1066 buf.extend_from_slice(&[0xdd, 0x00, 0xff, 0xff, 0xff]);
1067 }
1068 let err = rmp_serde::from_slice::<JsonData>(&buf)
1069 .unwrap_err()
1070 .to_string();
1071 assert!(err.contains("nesting depth"), "{err}");
1072 }
1073}