1use alloc::string::String;
7use alloc::vec::Vec;
8use core::fmt;
9use azul_css::{
10 AzString, OptionString, OptionF64, OptionBool,
11 impl_vec, impl_vec_clone, impl_vec_debug, impl_vec_partialeq, impl_vec_mut,
12 impl_result, impl_result_inner,
13 impl_option, impl_option_inner,
14};
15
16#[derive(Debug, Clone, PartialEq)]
22#[repr(C)]
23pub struct Json {
24 pub value_type: JsonType,
26 pub internal: JsonInternal,
29}
30
31#[derive(Debug, Clone, PartialEq)]
39#[repr(C)]
40pub struct JsonInternal {
41 pub string_value: AzString,
43 pub number_value: f64,
45 pub bool_value: bool,
47}
48
49impl Default for Json {
52 fn default() -> Self {
53 Self::null()
54 }
55}
56
57impl Default for JsonInternal {
58 fn default() -> Self {
59 Self {
60 string_value: AzString::from(String::new()),
61 number_value: 0.0,
62 bool_value: false,
63 }
64 }
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
69#[repr(C)]
70pub enum JsonType {
71 Null,
73 Bool,
75 Number,
77 String,
79 Array,
81 Object,
83}
84
85#[derive(Debug, Clone, PartialEq, Eq)]
87#[repr(C)]
88pub struct JsonParseError {
89 pub message: AzString,
91 pub line: u32,
93 pub column: u32,
95}
96
97impl fmt::Display for JsonParseError {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 if self.line > 0 {
100 write!(f, "{}:{}: {}", self.line, self.column, self.message.as_str())
101 } else {
102 write!(f, "{}", self.message.as_str())
103 }
104 }
105}
106
107#[cfg(feature = "std")]
108impl std::error::Error for JsonParseError {}
109
110#[derive(Debug, Clone, PartialEq)]
112#[repr(C)]
113pub struct JsonKeyValue {
114 pub key: AzString,
116 pub value: Json,
118}
119
120impl JsonKeyValue {
121 #[must_use] pub const fn create(key: AzString, value: Json) -> Self {
123 Self { key, value }
124 }
125}
126
127impl_option!(JsonKeyValue, OptionJsonKeyValue, copy = false, [Debug, Clone, PartialEq]);
133
134impl_vec!(JsonKeyValue, JsonKeyValueVec, JsonKeyValueVecDestructor, JsonKeyValueVecDestructorType, JsonKeyValueVecSlice, OptionJsonKeyValue);
136impl_vec_clone!(JsonKeyValue, JsonKeyValueVec, JsonKeyValueVecDestructor);
137impl_vec_debug!(JsonKeyValue, JsonKeyValueVec);
138
139impl JsonKeyValueVec {
140 #[inline]
142 #[allow(clippy::not_unsafe_ptr_arg_deref)] #[must_use] pub fn copy_from_array(ptr: *const JsonKeyValue, len: usize) -> Self {
144 if ptr.is_null() || len == 0 {
145 return Self::new();
146 }
147 let slice = unsafe { core::slice::from_raw_parts(ptr, len) };
148 Self::from_vec(slice.to_vec())
149 }
150}
151
152impl_vec!(Json, JsonVec, JsonVecDestructor, JsonVecDestructorType, JsonVecSlice, OptionJson);
154impl_vec_clone!(Json, JsonVec, JsonVecDestructor);
155impl_vec_debug!(Json, JsonVec);
156impl_vec_partialeq!(Json, JsonVec);
157impl_vec_mut!(Json, JsonVec);
158
159impl JsonVec {
160 #[inline]
162 #[allow(clippy::not_unsafe_ptr_arg_deref)] #[must_use] pub fn copy_from_array(ptr: *const Json, len: usize) -> Self {
164 if ptr.is_null() || len == 0 {
165 return Self::new();
166 }
167 let slice = unsafe { core::slice::from_raw_parts(ptr, len) };
168 Self::from_vec(slice.to_vec())
169 }
170}
171
172impl_result!(
174 Json,
175 JsonParseError,
176 ResultJsonJsonParseError,
177 copy = false,
178 [Debug, Clone, PartialEq]
179);
180
181impl_option!(Json, OptionJson, copy = false, [Clone, Debug, PartialEq]);
183impl_option!(JsonVec, OptionJsonVec, copy = false, [Clone, Debug]);
184impl_option!(JsonKeyValueVec, OptionJsonKeyValueVec, copy = false, [Clone, Debug]);
185
186impl_option!(i64, OptionI64, [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]);
189
190#[allow(clippy::cast_possible_truncation)] fn f64_as_i64(n: f64) -> Option<i64> {
202 if n.fract() == 0.0 && n >= -(2_f64.powi(63)) && n < 2_f64.powi(63) {
203 Some(n as i64)
204 } else {
205 None
206 }
207}
208
209impl Json {
214 #[must_use] pub fn null() -> Self {
216 Self {
217 value_type: JsonType::Null,
218 internal: JsonInternal::default(),
219 }
220 }
221
222 #[must_use] pub fn bool(value: bool) -> Self {
224 Self {
225 value_type: JsonType::Bool,
226 internal: JsonInternal {
227 string_value: AzString::from(String::new()),
228 number_value: 0.0,
229 bool_value: value,
230 },
231 }
232 }
233
234 #[must_use] pub fn number(value: f64) -> Self {
236 Self {
237 value_type: JsonType::Number,
238 internal: JsonInternal {
239 string_value: AzString::from(String::new()),
240 number_value: value,
241 bool_value: false,
242 },
243 }
244 }
245
246 #[allow(clippy::cast_precision_loss)] #[must_use] pub fn integer(value: i64) -> Self {
252 Self {
253 value_type: JsonType::Number,
254 internal: JsonInternal {
255 string_value: AzString::from(String::new()),
256 number_value: value as f64,
257 bool_value: false,
258 },
259 }
260 }
261
262 pub fn string(value: impl Into<String>) -> Self {
264 Self {
265 value_type: JsonType::String,
266 internal: JsonInternal {
267 string_value: AzString::from(value.into()),
268 number_value: 0.0,
269 bool_value: false,
270 },
271 }
272 }
273
274 #[must_use] pub fn is_null(&self) -> bool {
276 self.value_type == JsonType::Null
277 }
278
279 #[must_use] pub fn is_bool(&self) -> bool {
281 self.value_type == JsonType::Bool
282 }
283
284 #[must_use] pub fn is_number(&self) -> bool {
286 self.value_type == JsonType::Number
287 }
288
289 #[must_use] pub fn is_string(&self) -> bool {
291 self.value_type == JsonType::String
292 }
293
294 #[must_use] pub fn is_array(&self) -> bool {
296 self.value_type == JsonType::Array
297 }
298
299 #[must_use] pub fn is_object(&self) -> bool {
301 self.value_type == JsonType::Object
302 }
303
304 #[must_use] pub fn as_bool(&self) -> OptionBool {
306 if self.value_type == JsonType::Bool {
307 OptionBool::Some(self.internal.bool_value)
308 } else {
309 OptionBool::None
310 }
311 }
312
313 #[must_use] pub fn as_number(&self) -> OptionF64 {
315 if self.value_type == JsonType::Number {
316 OptionF64::Some(self.internal.number_value)
317 } else {
318 OptionF64::None
319 }
320 }
321
322 #[must_use] pub fn as_i64(&self) -> OptionI64 {
324 if self.value_type == JsonType::Number {
325 f64_as_i64(self.internal.number_value).map_or(OptionI64::None, OptionI64::Some)
326 } else {
327 OptionI64::None
328 }
329 }
330
331 #[must_use] pub fn as_string(&self) -> OptionString {
333 if self.value_type == JsonType::String {
334 OptionString::Some(self.internal.string_value.clone())
335 } else {
336 OptionString::None
337 }
338 }
339
340 #[must_use] pub fn raw_string(&self) -> &str {
342 self.internal.string_value.as_str()
343 }
344}
345
346impl fmt::Display for Json {
351 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
352 match self.value_type {
353 JsonType::Null => write!(f, "null"),
354 JsonType::Bool => write!(f, "{}", self.internal.bool_value),
355 JsonType::Number => {
356 let num = self.internal.number_value;
357 if let Some(i) = f64_as_i64(num) {
358 write!(f, "{i}")
359 } else {
360 write!(f, "{num}")
361 }
362 }
363 JsonType::String => write!(f, "\"{}\"", self.internal.string_value.as_str()),
364 JsonType::Array | JsonType::Object => {
365 write!(f, "{}", self.internal.string_value.as_str())
366 }
367 }
368 }
369}
370
371#[cfg(feature = "serde-json")]
376impl serde::Serialize for Json {
377 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
384 self.to_serde_value().serialize(s)
385 }
386}
387
388#[cfg(feature = "serde-json")]
389impl<'de> serde::Deserialize<'de> for Json {
390 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
391 Ok(Self::from_serde_value(serde_json::Value::deserialize(d)?))
392 }
393}
394
395#[cfg(feature = "serde-json")]
396impl Json {
397 pub fn parse(s: &str) -> Result<Self, JsonParseError> {
404 let value: serde_json::Value = serde_json::from_str(s).map_err(|e| {
405 JsonParseError {
406 message: AzString::from(alloc::format!("{e}")),
407 line: u32::try_from(e.line()).unwrap_or(u32::MAX),
408 column: u32::try_from(e.column()).unwrap_or(u32::MAX),
409 }
410 })?;
411 Ok(Self::from_serde_value(value))
412 }
413
414 pub fn parse_bytes(bytes: &[u8]) -> Result<Self, JsonParseError> {
421 let value: serde_json::Value = serde_json::from_slice(bytes).map_err(|e| {
422 JsonParseError {
423 message: AzString::from(alloc::format!("{e}")),
424 line: u32::try_from(e.line()).unwrap_or(u32::MAX),
425 column: u32::try_from(e.column()).unwrap_or(u32::MAX),
426 }
427 })?;
428 Ok(Self::from_serde_value(value))
429 }
430
431 #[must_use] pub fn from_serde_value(value: serde_json::Value) -> Self {
433 match value {
434 serde_json::Value::Null => Self::null(),
435 serde_json::Value::Bool(b) => Self::bool(b),
436 serde_json::Value::Number(n) => Self::number(n.as_f64().unwrap_or(0.0)),
437 serde_json::Value::String(s) => Self::string(s),
438 serde_json::Value::Array(arr) => {
439 let json_str = serde_json::to_string(&serde_json::Value::Array(arr)).unwrap_or_default();
440 Self {
441 value_type: JsonType::Array,
442 internal: JsonInternal {
443 string_value: AzString::from(json_str),
444 number_value: 0.0,
445 bool_value: false,
446 },
447 }
448 }
449 serde_json::Value::Object(obj) => {
450 let json_str = serde_json::to_string(&serde_json::Value::Object(obj)).unwrap_or_default();
451 Self {
452 value_type: JsonType::Object,
453 internal: JsonInternal {
454 string_value: AzString::from(json_str),
455 number_value: 0.0,
456 bool_value: false,
457 },
458 }
459 }
460 }
461 }
462
463 #[must_use]
465 pub fn to_serde_value(&self) -> serde_json::Value {
466 match self.value_type {
467 JsonType::Null => serde_json::Value::Null,
468 JsonType::Bool => serde_json::Value::Bool(self.internal.bool_value),
469 JsonType::Number => {
470 let num = self.internal.number_value;
471 f64_as_i64(num).map_or_else(
472 || {
473 serde_json::Number::from_f64(num)
474 .map_or(serde_json::Value::Null, serde_json::Value::Number)
475 },
476 |i| serde_json::Value::Number(serde_json::Number::from(i)),
477 )
478 }
479 JsonType::String => serde_json::Value::String(self.internal.string_value.as_str().to_string()),
480 JsonType::Array | JsonType::Object => {
481 serde_json::from_str(self.internal.string_value.as_str())
482 .unwrap_or(serde_json::Value::Null)
483 }
484 }
485 }
486
487 #[allow(clippy::needless_pass_by_value)]
490 #[must_use] pub fn array(values: JsonVec) -> Self {
491 let serde_array: Vec<serde_json::Value> = values
492 .as_slice()
493 .iter()
494 .map(Self::to_serde_value)
495 .collect();
496 let json_str = serde_json::to_string(&serde_json::Value::Array(serde_array))
497 .unwrap_or_else(|_| "[]".to_string());
498 Self {
499 value_type: JsonType::Array,
500 internal: JsonInternal {
501 string_value: AzString::from(json_str),
502 number_value: 0.0,
503 bool_value: false,
504 },
505 }
506 }
507
508 #[allow(clippy::needless_pass_by_value)]
511 #[must_use] pub fn object(entries: JsonKeyValueVec) -> Self {
512 let mut map = serde_json::Map::new();
513 for kv in entries.as_slice() {
514 map.insert(kv.key.as_str().to_string(), kv.value.to_serde_value());
515 }
516 let json_str = serde_json::to_string(&serde_json::Value::Object(map))
517 .unwrap_or_else(|_| "{}".to_string());
518 Self {
519 value_type: JsonType::Object,
520 internal: JsonInternal {
521 string_value: AzString::from(json_str),
522 number_value: 0.0,
523 bool_value: false,
524 },
525 }
526 }
527
528 #[must_use] pub fn len(&self) -> usize {
530 match self.value_type {
531 JsonType::Array => {
532 if let Ok(serde_json::Value::Array(arr)) = serde_json::from_str(self.internal.string_value.as_str()) {
533 arr.len()
534 } else {
535 0
536 }
537 }
538 JsonType::Object => {
539 if let Ok(serde_json::Value::Object(obj)) = serde_json::from_str(self.internal.string_value.as_str()) {
540 obj.len()
541 } else {
542 0
543 }
544 }
545 _ => 0,
546 }
547 }
548
549 #[must_use] pub fn is_empty(&self) -> bool {
551 self.len() == 0
552 }
553
554 #[must_use] pub fn get_index(&self, index: usize) -> Option<Self> {
556 if self.value_type != JsonType::Array { return None; }
557 let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
558 if let serde_json::Value::Array(arr) = value {
559 arr.get(index).map(|v| Self::from_serde_value(v.clone()))
560 } else {
561 None
562 }
563 }
564
565 #[must_use] pub fn get_key(&self, key: &str) -> Option<Self> {
567 if self.value_type != JsonType::Object { return None; }
568 let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
569 if let serde_json::Value::Object(obj) = value {
570 obj.get(key).map(|v| Self::from_serde_value(v.clone()))
571 } else {
572 None
573 }
574 }
575
576 #[must_use] pub fn keys(&self) -> Vec<AzString> {
578 if self.value_type != JsonType::Object { return Vec::new(); }
579 let value: serde_json::Value = match serde_json::from_str(self.internal.string_value.as_str()) {
580 Ok(v) => v,
581 Err(_) => return Vec::new(),
582 };
583 if let serde_json::Value::Object(obj) = value {
584 obj.keys().map(|k| AzString::from(k.clone())).collect()
585 } else {
586 Vec::new()
587 }
588 }
589
590 pub fn to_array(&self) -> Option<JsonVec> {
592 if self.value_type != JsonType::Array { return None; }
593 let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
594 if let serde_json::Value::Array(arr) = value {
595 Some(arr.into_iter().map(Self::from_serde_value).collect())
596 } else {
597 None
598 }
599 }
600
601 #[must_use] pub fn to_object(&self) -> Option<JsonKeyValueVec> {
603 if self.value_type != JsonType::Object { return None; }
604 let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
605 if let serde_json::Value::Object(obj) = value {
606 Some(obj.into_iter().map(|(k, v)| JsonKeyValue {
607 key: AzString::from(k),
608 value: Self::from_serde_value(v),
609 }).collect())
610 } else {
611 None
612 }
613 }
614
615 #[must_use] pub fn to_json_string(&self) -> AzString {
617 match self.value_type {
618 JsonType::Null => AzString::from(alloc::string::String::from("null")),
619 JsonType::Bool => AzString::from(if self.internal.bool_value { alloc::string::String::from("true") } else { alloc::string::String::from("false") }),
620 JsonType::Number => {
621 let num = self.internal.number_value;
622 f64_as_i64(num).map_or_else(
623 || AzString::from(alloc::format!("{num}")),
624 |i| AzString::from(alloc::format!("{i}")),
625 )
626 }
627 JsonType::String => {
628 let escaped = serde_json::to_string(self.internal.string_value.as_str()).unwrap_or_default();
629 AzString::from(escaped)
630 }
631 JsonType::Array | JsonType::Object => {
632 self.internal.string_value.clone()
633 }
634 }
635 }
636
637 #[must_use] pub fn to_string_pretty(&self) -> AzString {
639 match self.value_type {
640 JsonType::Null | JsonType::Bool | JsonType::Number | JsonType::String => {
641 self.to_json_string()
642 }
643 JsonType::Array | JsonType::Object => {
644 serde_json::from_str::<serde_json::Value>(self.internal.string_value.as_str())
645 .map_or_else(
646 |_| self.internal.string_value.clone(),
647 |value| {
648 AzString::from(
649 serde_json::to_string_pretty(&value).unwrap_or_default(),
650 )
651 },
652 )
653 }
654 }
655 }
656
657 #[must_use] pub fn jq(&self, path: &str) -> Self {
659 match self.value_type {
660 JsonType::Null | JsonType::Bool | JsonType::Number | JsonType::String => {
661 if path.is_empty() { self.clone() } else { Self::null() }
662 }
663 JsonType::Array | JsonType::Object => {
664 let value: serde_json::Value = match serde_json::from_str(self.internal.string_value.as_str()) {
665 Ok(v) => v,
666 Err(_) => return Self::null(),
667 };
668 value
669 .pointer(path)
670 .map_or_else(Self::null, |v| Self::from_serde_value(v.clone()))
671 }
672 }
673 }
674
675 #[must_use] pub fn jq_all(&self, path: &str) -> JsonVec {
677 let result = match self.value_type {
678 JsonType::Null | JsonType::Bool | JsonType::Number | JsonType::String => {
679 if path.is_empty() { vec![self.clone()] } else { vec![] }
680 }
681 JsonType::Array | JsonType::Object => {
682 let value: serde_json::Value = match serde_json::from_str(self.internal.string_value.as_str()) {
683 Ok(v) => v,
684 Err(_) => return JsonVec::from_vec(vec![]),
685 };
686 Self::jq_all_recursive(&value, path)
687 }
688 };
689 JsonVec::from_vec(result)
690 }
691
692 const JQ_MAX_WILDCARD_DEPTH: usize = 512;
701
702 fn jq_all_recursive(value: &serde_json::Value, path: &str) -> Vec<Self> {
708 Self::jq_all_recursive_depth(value, path, 0)
709 }
710
711 fn jq_all_recursive_depth(
712 value: &serde_json::Value,
713 path: &str,
714 depth: usize,
715 ) -> Vec<Self> {
716 if depth > Self::JQ_MAX_WILDCARD_DEPTH {
719 return vec![];
720 }
721
722 let mut value = value;
724 let mut path = path;
725 loop {
726 if path.is_empty() {
727 return vec![Self::from_serde_value(value.clone())];
728 }
729 if !path.starts_with('/') {
730 return vec![];
731 }
732 let rest = &path[1..];
733 let (component, remaining) =
734 rest.find('/').map_or((rest, ""), |idx| (&rest[..idx], &rest[idx..]));
735
736 if component == "*" {
737 let mut results = Vec::new();
738 match value {
739 serde_json::Value::Array(arr) => {
740 for item in arr {
741 results.extend(Self::jq_all_recursive_depth(
742 item,
743 remaining,
744 depth + 1,
745 ));
746 }
747 }
748 serde_json::Value::Object(obj) => {
749 for (_key, val) in obj {
750 results.extend(Self::jq_all_recursive_depth(
751 val,
752 remaining,
753 depth + 1,
754 ));
755 }
756 }
757 _ => {}
758 }
759 return results;
760 }
761
762 let next = match value {
764 serde_json::Value::Array(arr) => {
765 component.parse::<usize>().ok().and_then(|idx| arr.get(idx))
766 }
767 serde_json::Value::Object(obj) => obj.get(component),
768 _ => None,
769 };
770 match next {
771 Some(v) => {
772 value = v;
773 path = remaining;
774 }
775 None => return vec![],
776 }
777 }
778 }
779}
780
781#[cfg(test)]
782mod jq_recursion_tests {
783 use super::*;
784
785 #[test]
792 #[cfg(feature = "serde-json")]
793 fn huge_pointer_on_shallow_doc_returns_empty() {
794 let json = Json::parse("{\"a\":{\"b\":1}}").expect("parse");
795 let pointer = "/a".repeat(200_000);
796 assert_eq!(json.jq_all(&pointer).as_ref().len(), 0);
797 }
798
799 #[test]
802 #[cfg(feature = "serde-json")]
803 fn deep_linear_pointer_resolves_leaf() {
804 const DEPTH: usize = 100; let mut doc = String::new();
807 for _ in 0..DEPTH {
808 doc.push_str("{\"a\":");
809 }
810 doc.push_str("42");
811 for _ in 0..DEPTH {
812 doc.push('}');
813 }
814
815 let json = Json::parse(&doc).expect("deep doc should parse");
816 let pointer = "/a".repeat(DEPTH);
817 let out = json.jq_all(&pointer);
818 assert_eq!(out.as_ref().len(), 1, "the single leaf should be found");
819 }
820
821 #[test]
823 #[cfg(feature = "serde-json")]
824 fn wildcard_and_index_still_work() {
825 let json = Json::parse("{\"items\":[{\"v\":1},{\"v\":2},{\"v\":3}]}").expect("parse");
826 let all = json.jq_all("/items/*/v");
827 assert_eq!(all.as_ref().len(), 3);
828 let one = json.jq_all("/items/1/v");
829 assert_eq!(one.as_ref().len(), 1);
830 }
831}
832
833#[cfg(test)]
834#[allow(clippy::float_cmp, clippy::unreadable_literal)]
835mod autotest_generated {
836 use super::*;
837
838 fn az(s: &str) -> AzString {
843 AzString::from(String::from(s))
844 }
845
846 fn raw(value_type: JsonType, string_value: &str) -> Json {
851 Json {
852 value_type,
853 internal: JsonInternal {
854 string_value: az(string_value),
855 number_value: 0.0,
856 bool_value: false,
857 },
858 }
859 }
860
861 fn two_pow_63() -> f64 {
862 2_f64.powi(63)
863 }
864
865 #[test]
870 fn f64_as_i64_zero_and_negative_zero() {
871 assert_eq!(f64_as_i64(0.0), Some(0));
872 assert_eq!(f64_as_i64(-0.0), Some(0));
874 }
875
876 #[test]
877 fn f64_as_i64_min_max_boundaries() {
878 assert_eq!(f64_as_i64(-two_pow_63()), Some(i64::MIN));
880 assert_eq!(f64_as_i64(two_pow_63()), None);
882 #[allow(clippy::cast_precision_loss)]
885 let max_as_f64 = i64::MAX as f64;
886 assert_eq!(max_as_f64, two_pow_63());
887 assert_eq!(f64_as_i64(max_as_f64), None);
888 let just_below = two_pow_63() - 1024.0;
890 assert_eq!(f64_as_i64(just_below), Some(9_223_372_036_854_774_784));
891 }
892
893 #[test]
894 fn f64_as_i64_negatives_are_deterministic() {
895 assert_eq!(f64_as_i64(-1.0), Some(-1));
896 assert_eq!(f64_as_i64(-42.0), Some(-42));
897 assert_eq!(f64_as_i64(-0.5), None);
898 assert_eq!(f64_as_i64(-1.0 - f64::EPSILON), None);
899 assert_eq!(f64_as_i64(-two_pow_63() * (1.0 + f64::EPSILON)), None);
901 }
902
903 #[test]
904 fn f64_as_i64_overflow_inputs_return_none_not_a_wrapped_cast() {
905 for n in [
906 1e19_f64,
907 1e300_f64,
908 -1e300_f64,
909 f64::MAX,
910 f64::MIN,
911 two_pow_63() * 2.0,
912 ] {
913 assert_eq!(f64_as_i64(n), None, "{n} must not be cast to i64");
914 }
915 }
916
917 #[test]
918 fn f64_as_i64_nan_and_infinity_do_not_panic() {
919 assert_eq!(f64_as_i64(f64::NAN), None);
922 assert_eq!(f64_as_i64(f64::INFINITY), None);
923 assert_eq!(f64_as_i64(f64::NEG_INFINITY), None);
924 }
925
926 #[test]
927 fn f64_as_i64_fractional_and_subnormal_return_none() {
928 assert_eq!(f64_as_i64(0.5), None);
929 assert_eq!(f64_as_i64(f64::EPSILON), None);
930 assert_eq!(f64_as_i64(f64::MIN_POSITIVE), None);
931 assert_eq!(f64_as_i64(f64::from_bits(1)), None);
933 }
934
935 #[test]
940 fn number_stores_nan_and_infinity_without_panicking() {
941 for n in [f64::NAN, f64::INFINITY, f64::NEG_INFINITY] {
942 let j = Json::number(n);
943 assert!(j.is_number());
944 assert_eq!(j.as_i64(), OptionI64::None);
945 match j.as_number() {
946 OptionF64::Some(v) => assert_eq!(v.is_nan(), n.is_nan()),
947 OptionF64::None => panic!("as_number() must be Some for a Number"),
948 }
949 let s = alloc::format!("{j}");
951 assert!(!s.is_empty());
952 }
953 }
954
955 #[test]
956 fn number_min_max_and_zero() {
957 assert_eq!(Json::number(0.0).as_i64(), OptionI64::Some(0));
958 assert_eq!(Json::number(-0.0).as_i64(), OptionI64::Some(0));
959 assert_eq!(Json::number(f64::MAX).as_number(), OptionF64::Some(f64::MAX));
960 assert_eq!(Json::number(f64::MIN).as_number(), OptionF64::Some(f64::MIN));
961 assert_eq!(Json::number(f64::MAX).as_i64(), OptionI64::None);
963 }
964
965 #[test]
966 fn integer_min_round_trips_but_max_does_not() {
967 assert_eq!(Json::integer(i64::MIN).as_i64(), OptionI64::Some(i64::MIN));
969 assert_eq!(Json::integer(i64::MAX).as_i64(), OptionI64::None);
973 assert_eq!(
974 Json::integer(i64::MAX).as_number(),
975 OptionF64::Some(two_pow_63())
976 );
977 }
978
979 #[test]
980 fn integer_silently_loses_precision_above_2_pow_53() {
981 let boundary = 1_i64 << 53; assert_eq!(Json::integer(boundary).as_i64(), OptionI64::Some(boundary));
983 assert_eq!(
985 Json::integer(boundary + 1).as_i64(),
986 OptionI64::Some(boundary)
987 );
988 assert_eq!(Json::integer(0).as_i64(), OptionI64::Some(0));
989 assert_eq!(Json::integer(-1).as_i64(), OptionI64::Some(-1));
990 }
991
992 #[test]
997 fn predicates_are_mutually_exclusive_for_every_type() {
998 let cases = [
999 (Json::null(), JsonType::Null),
1000 (Json::bool(false), JsonType::Bool),
1001 (Json::number(f64::NAN), JsonType::Number),
1002 (Json::integer(0), JsonType::Number),
1003 (Json::string(""), JsonType::String),
1004 (raw(JsonType::Array, "[]"), JsonType::Array),
1005 (raw(JsonType::Object, "{}"), JsonType::Object),
1006 ];
1007 for (j, ty) in &cases {
1008 let flags = [
1009 j.is_null(),
1010 j.is_bool(),
1011 j.is_number(),
1012 j.is_string(),
1013 j.is_array(),
1014 j.is_object(),
1015 ];
1016 assert_eq!(
1017 flags.iter().filter(|b| **b).count(),
1018 1,
1019 "exactly one predicate must hold for {ty:?}"
1020 );
1021 assert_eq!(j.value_type, *ty);
1022 }
1023 }
1024
1025 #[test]
1026 fn predicates_on_a_default_internal_do_not_panic() {
1027 for ty in [
1029 JsonType::Null,
1030 JsonType::Bool,
1031 JsonType::Number,
1032 JsonType::String,
1033 JsonType::Array,
1034 JsonType::Object,
1035 ] {
1036 let j = Json {
1037 value_type: ty,
1038 internal: JsonInternal::default(),
1039 };
1040 assert_eq!(j.is_null(), ty == JsonType::Null);
1041 assert_eq!(j.is_object(), ty == JsonType::Object);
1042 assert_eq!(j.raw_string(), "");
1043 }
1044 }
1045
1046 #[test]
1047 fn bool_constructor_keeps_both_values() {
1048 assert_eq!(Json::bool(true).as_bool(), OptionBool::Some(true));
1049 assert_eq!(Json::bool(false).as_bool(), OptionBool::Some(false));
1050 assert_eq!(Json::bool(true).raw_string(), "");
1052 assert_eq!(Json::bool(true).as_number(), OptionF64::None);
1053 }
1054
1055 #[test]
1056 fn string_constructor_handles_empty_unicode_and_huge_inputs() {
1057 assert_eq!(Json::string("").as_string(), OptionString::Some(az("")));
1058
1059 let unicode = "π nÑïve \u{0301}\u{202e}\0 δΈζ";
1060 assert_eq!(
1061 Json::string(unicode).as_string(),
1062 OptionString::Some(az(unicode))
1063 );
1064 assert_eq!(Json::string(unicode).raw_string(), unicode);
1065
1066 let huge = "a".repeat(1_000_000);
1067 let j = Json::string(huge.clone());
1068 assert_eq!(j.raw_string().len(), 1_000_000);
1069 assert_eq!(j.as_string(), OptionString::Some(AzString::from(huge)));
1070 }
1071
1072 #[test]
1077 fn getters_return_none_on_type_mismatch() {
1078 let null = Json::null();
1079 assert_eq!(null.as_bool(), OptionBool::None);
1080 assert_eq!(null.as_number(), OptionF64::None);
1081 assert_eq!(null.as_i64(), OptionI64::None);
1082 assert_eq!(null.as_string(), OptionString::None);
1083
1084 let mut liar = Json::bool(true);
1087 liar.internal.number_value = 7.0;
1088 liar.internal.string_value = az("7");
1089 assert_eq!(liar.as_number(), OptionF64::None);
1090 assert_eq!(liar.as_i64(), OptionI64::None);
1091 assert_eq!(liar.as_string(), OptionString::None);
1092 assert_eq!(liar.as_bool(), OptionBool::Some(true));
1093 assert_eq!(liar.raw_string(), "7");
1095 }
1096
1097 #[test]
1098 fn raw_string_is_empty_for_scalars_and_serialized_for_containers() {
1099 assert_eq!(Json::null().raw_string(), "");
1100 assert_eq!(Json::bool(true).raw_string(), "");
1101 assert_eq!(Json::number(1.5).raw_string(), "");
1102 assert_eq!(Json::string("hi").raw_string(), "hi");
1103 assert_eq!(raw(JsonType::Array, "[1,2]").raw_string(), "[1,2]");
1104 assert_eq!(raw(JsonType::Object, "{not json").raw_string(), "{not json");
1106 }
1107
1108 #[test]
1113 fn display_scalar_values() {
1114 assert_eq!(alloc::format!("{}", Json::null()), "null");
1115 assert_eq!(alloc::format!("{}", Json::bool(true)), "true");
1116 assert_eq!(alloc::format!("{}", Json::bool(false)), "false");
1117 assert_eq!(alloc::format!("{}", Json::number(3.0)), "3");
1119 assert_eq!(alloc::format!("{}", Json::integer(-42)), "-42");
1120 assert_eq!(alloc::format!("{}", Json::number(1.5)), "1.5");
1121 assert_eq!(alloc::format!("{}", Json::string("x")), "\"x\"");
1122 }
1123
1124 #[test]
1125 fn display_of_non_finite_numbers_is_not_json() {
1126 assert_eq!(alloc::format!("{}", Json::number(f64::NAN)), "NaN");
1128 assert_eq!(alloc::format!("{}", Json::number(f64::INFINITY)), "inf");
1129 assert_eq!(alloc::format!("{}", Json::number(f64::NEG_INFINITY)), "-inf");
1130 assert_eq!(alloc::format!("{}", Json::number(-0.0)), "0");
1132 }
1133
1134 #[test]
1135 fn display_does_not_escape_strings() {
1136 let j = Json::string("a\"b\nc");
1139 assert_eq!(alloc::format!("{j}"), "\"a\"b\nc\"");
1140 }
1141
1142 #[test]
1143 fn display_of_container_emits_the_raw_payload_even_when_corrupt() {
1144 assert_eq!(
1145 alloc::format!("{}", raw(JsonType::Array, "[1, 2]")),
1146 "[1, 2]"
1147 );
1148 assert_eq!(
1149 alloc::format!("{}", raw(JsonType::Object, "<<garbage>>")),
1150 "<<garbage>>"
1151 );
1152 assert_eq!(alloc::format!("{}", raw(JsonType::Array, "")), "");
1153 }
1154
1155 #[test]
1160 fn parse_error_display_with_and_without_position() {
1161 let with_pos = JsonParseError {
1162 message: az("expected value"),
1163 line: 3,
1164 column: 7,
1165 };
1166 assert_eq!(alloc::format!("{with_pos}"), "3:7: expected value");
1167
1168 let no_pos = JsonParseError {
1169 message: az("expected value"),
1170 line: 0,
1171 column: 99,
1172 };
1173 assert_eq!(alloc::format!("{no_pos}"), "expected value");
1174 }
1175
1176 #[test]
1177 fn parse_error_display_edge_values_do_not_panic() {
1178 let empty = JsonParseError {
1179 message: az(""),
1180 line: 0,
1181 column: 0,
1182 };
1183 assert_eq!(alloc::format!("{empty}"), "");
1184
1185 let maxed = JsonParseError {
1186 message: az("π"),
1187 line: u32::MAX,
1188 column: u32::MAX,
1189 };
1190 assert_eq!(
1191 alloc::format!("{maxed}"),
1192 alloc::format!("{}:{}: π", u32::MAX, u32::MAX)
1193 );
1194 }
1195
1196 #[test]
1201 fn key_value_create_preserves_key_and_value() {
1202 let kv = JsonKeyValue::create(az(""), Json::null());
1203 assert_eq!(kv.key.as_str(), "");
1204 assert!(kv.value.is_null());
1205
1206 let big_key = "k".repeat(100_000);
1207 let kv = JsonKeyValue::create(
1208 AzString::from(big_key.clone()),
1209 Json::number(f64::NEG_INFINITY),
1210 );
1211 assert_eq!(kv.key.as_str().len(), big_key.len());
1212 assert!(kv.value.is_number());
1213
1214 let kv = JsonKeyValue::create(az("π/\u{0}"), Json::string("v"));
1215 assert_eq!(kv.key.as_str(), "π/\u{0}");
1216 assert_eq!(kv.value.as_string(), OptionString::Some(az("v")));
1217 }
1218
1219 #[test]
1224 fn json_vec_copy_from_array_null_ptr_is_empty_even_at_usize_max_len() {
1225 let v = JsonVec::copy_from_array(core::ptr::null(), 0);
1228 assert!(v.is_empty());
1229 let v = JsonVec::copy_from_array(core::ptr::null(), usize::MAX);
1230 assert!(v.is_empty());
1231 assert_eq!(v.len(), 0);
1232 }
1233
1234 #[test]
1235 fn json_vec_copy_from_array_zero_len_with_valid_ptr_is_empty() {
1236 let items = [Json::null(), Json::bool(true)];
1237 let v = JsonVec::copy_from_array(items.as_ptr(), 0);
1238 assert!(v.is_empty());
1239 }
1240
1241 #[test]
1242 fn json_vec_copy_from_array_deep_copies_the_elements() {
1243 let items = vec![
1244 Json::null(),
1245 Json::bool(true),
1246 Json::number(f64::NAN),
1247 Json::string("π"),
1248 ];
1249 let v = JsonVec::copy_from_array(items.as_ptr(), items.len());
1250 assert_eq!(v.len(), 4);
1251 assert_eq!(v.as_slice()[3].as_string(), OptionString::Some(az("π")));
1252 drop(items);
1254 assert!(v.as_slice()[0].is_null());
1255 assert_eq!(v.as_slice()[1].as_bool(), OptionBool::Some(true));
1256 assert_eq!(v.as_slice()[3].raw_string(), "π");
1257 }
1258
1259 #[test]
1260 fn key_value_vec_copy_from_array_null_ptr_is_empty_even_at_usize_max_len() {
1261 let v = JsonKeyValueVec::copy_from_array(core::ptr::null(), 0);
1262 assert!(v.is_empty());
1263 let v = JsonKeyValueVec::copy_from_array(core::ptr::null(), usize::MAX);
1264 assert!(v.is_empty());
1265 assert_eq!(v.len(), 0);
1266 }
1267
1268 #[test]
1269 fn key_value_vec_copy_from_array_deep_copies_the_elements() {
1270 let items = vec![
1271 JsonKeyValue::create(az("a"), Json::integer(1)),
1272 JsonKeyValue::create(az(""), Json::null()),
1273 ];
1274 let v = JsonKeyValueVec::copy_from_array(items.as_ptr(), items.len());
1275 assert_eq!(v.len(), 2);
1276 let zero_len = JsonKeyValueVec::copy_from_array(items.as_ptr(), 0);
1277 assert!(zero_len.is_empty());
1278 drop(items);
1279 assert_eq!(v.as_slice()[0].key.as_str(), "a");
1280 assert_eq!(v.as_slice()[0].value.as_i64(), OptionI64::Some(1));
1281 assert_eq!(v.as_slice()[1].key.as_str(), "");
1282 }
1283
1284 #[test]
1289 #[cfg(feature = "serde-json")]
1290 fn parse_empty_and_whitespace_only_input_is_an_error() {
1291 for s in ["", " ", " ", "\t\n\r", "\u{feff}"] {
1292 let err = Json::parse(s).expect_err("empty/blank input must not parse");
1293 assert!(!err.message.as_str().is_empty());
1294 assert!(Json::parse_bytes(s.as_bytes()).is_err());
1295 }
1296 assert!(Json::parse_bytes(b"").is_err());
1297 }
1298
1299 #[test]
1300 #[cfg(feature = "serde-json")]
1301 fn parse_garbage_returns_err_and_never_panics() {
1302 for s in [
1303 "{", "}", "[", "]", ",", ":", "nul", "tru", "'a'", "{,}", "[,]", "{\"a\"}", "{\"a\":}",
1304 "[1,]", "{\"a\":1,}", "\"unterminated", "\\", "\u{0}", "01", "+1", ".5", "1.", "-",
1305 "0x10", "--1", "1e", "{'a':1}", "undefined",
1306 ] {
1307 assert!(Json::parse(s).is_err(), "{s:?} must be rejected");
1308 assert!(Json::parse_bytes(s.as_bytes()).is_err(), "{s:?} (bytes)");
1309 }
1310 }
1311
1312 #[test]
1313 #[cfg(feature = "serde-json")]
1314 fn parse_leading_and_trailing_junk() {
1315 assert_eq!(Json::parse(" 1 ").expect("padded"), Json::integer(1));
1317 assert_eq!(Json::parse("\n\t{}\r\n").expect("padded"), Json::parse("{}").expect("{}"));
1318 for s in ["1;garbage", "{} {}", "null null", "1 2", "[1] x"] {
1320 assert!(Json::parse(s).is_err(), "{s:?} must be rejected");
1321 }
1322 }
1323
1324 #[test]
1325 #[cfg(feature = "serde-json")]
1326 fn parse_bytes_rejects_invalid_utf8_without_panicking() {
1327 assert!(Json::parse_bytes(&[0xFF, 0xFE, 0x00]).is_err());
1328 assert!(Json::parse_bytes(&[b'"', 0xFF, b'"']).is_err());
1330 assert!(Json::parse_bytes(&[b'[', 0x80, b']']).is_err());
1332 }
1333
1334 #[test]
1335 #[cfg(feature = "serde-json")]
1336 fn parse_deeply_nested_input_errors_instead_of_overflowing_the_stack() {
1337 let deep = alloc::format!("{}{}", "[".repeat(10_000), "]".repeat(10_000));
1339 assert!(Json::parse(&deep).is_err());
1340 assert!(Json::parse_bytes(deep.as_bytes()).is_err());
1341
1342 let deep_obj = alloc::format!("{}1{}", "{\"a\":".repeat(10_000), "}".repeat(10_000));
1343 assert!(Json::parse(&deep_obj).is_err());
1344
1345 let unbalanced = "[".repeat(100_000);
1347 assert!(Json::parse(&unbalanced).is_err());
1348 }
1349
1350 #[test]
1351 #[cfg(feature = "serde-json")]
1352 fn parse_extremely_long_input_terminates() {
1353 const N: usize = 200_000;
1354 let mut doc = String::with_capacity(N * 2 + 2);
1355 doc.push('[');
1356 for i in 0..N {
1357 if i > 0 {
1358 doc.push(',');
1359 }
1360 doc.push('1');
1361 }
1362 doc.push(']');
1363 let j = Json::parse(&doc).expect("a long flat array must parse");
1364 assert!(j.is_array());
1365 assert_eq!(j.len(), N);
1366
1367 let payload = "a".repeat(1_000_000);
1369 let j = Json::parse(&alloc::format!("\"{payload}\"")).expect("long string");
1370 assert_eq!(j.as_string(), OptionString::Some(AzString::from(payload)));
1371 }
1372
1373 #[test]
1374 #[cfg(feature = "serde-json")]
1375 fn parse_unicode_input() {
1376 let j = Json::parse("\"\u{1F600}\"").expect("emoji");
1377 assert_eq!(j.as_string(), OptionString::Some(az("\u{1F600}")));
1378
1379 let j = Json::parse("\"e\\u0301\\u202e\\u0000\"").expect("escapes");
1381 assert_eq!(
1382 j.as_string(),
1383 OptionString::Some(az("e\u{0301}\u{202e}\u{0}"))
1384 );
1385
1386 let j = Json::parse("{\"ΠΊΠ»ΡΡ\":\"Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅\"}").expect("cyrillic keys");
1388 assert_eq!(
1389 j.get_key("ΠΊΠ»ΡΡ").expect("key").as_string(),
1390 OptionString::Some(az("Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅"))
1391 );
1392
1393 assert!(Json::parse("\"\\ud800\"").is_err());
1395 }
1396
1397 #[test]
1398 #[cfg(feature = "serde-json")]
1399 fn parse_boundary_numbers() {
1400 assert_eq!(Json::parse("0").expect("0").as_i64(), OptionI64::Some(0));
1401 match Json::parse("-0").expect("-0").as_number() {
1403 OptionF64::Some(v) => assert_eq!(v, 0.0),
1404 OptionF64::None => panic!("-0 must be a number"),
1405 }
1406
1407 assert_eq!(
1409 Json::parse("-9223372036854775808").expect("i64::MIN").as_i64(),
1410 OptionI64::Some(i64::MIN)
1411 );
1412 let max = Json::parse("9223372036854775807").expect("i64::MAX");
1415 assert_eq!(max.as_number(), OptionF64::Some(two_pow_63()));
1416 assert_eq!(max.as_i64(), OptionI64::None);
1417 assert_eq!(
1419 Json::parse("18446744073709551615").expect("u64::MAX").as_i64(),
1420 OptionI64::None
1421 );
1422
1423 assert!(Json::parse("1e308").expect("1e308").is_number());
1424 assert!(Json::parse("1e-308").expect("1e-308").is_number());
1425
1426 for s in ["NaN", "nan", "Infinity", "-Infinity", "inf"] {
1428 assert!(Json::parse(s).is_err(), "{s:?} is not valid JSON");
1429 }
1430
1431 if let Ok(j) = Json::parse("1e400") {
1434 assert!(j.is_number());
1435 }
1436 if let Ok(j) = Json::parse("1e-400") {
1437 assert!(j.is_number());
1438 }
1439 }
1440
1441 #[test]
1442 #[cfg(feature = "serde-json")]
1443 fn parse_valid_minimal_inputs() {
1444 assert_eq!(Json::parse("null").expect("null"), Json::null());
1445 assert_eq!(Json::parse("true").expect("true"), Json::bool(true));
1446 assert_eq!(Json::parse("false").expect("false"), Json::bool(false));
1447 assert_eq!(Json::parse("1").expect("1"), Json::integer(1));
1448 assert_eq!(Json::parse("1.5").expect("1.5"), Json::number(1.5));
1449 assert_eq!(Json::parse("\"s\"").expect("str"), Json::string("s"));
1450 assert!(Json::parse("[]").expect("[]").is_array());
1451 assert!(Json::parse("{}").expect("{}").is_object());
1452 assert_eq!(
1454 Json::parse_bytes(b"{\"a\":[1,2]}").expect("bytes"),
1455 Json::parse("{\"a\":[1,2]}").expect("str")
1456 );
1457 }
1458
1459 #[cfg(feature = "serde-json")]
1464 fn round_trip_corpus() -> Vec<Json> {
1465 vec![
1466 Json::null(),
1467 Json::bool(true),
1468 Json::bool(false),
1469 Json::integer(0),
1470 Json::integer(-1),
1471 Json::integer(i64::MIN),
1472 Json::number(1.5),
1473 Json::number(-0.25),
1474 Json::number(1e21),
1475 Json::string(""),
1476 Json::string("π \"quoted\" \\slash\\ \n\t \u{0}"),
1477 Json::parse("[]").expect("[]"),
1478 Json::parse("{}").expect("{}"),
1479 Json::parse("[1,[2,[3]],{\"k\":null}]").expect("nested array"),
1480 Json::parse("{\"a\":{\"b\":[1,2,3]},\"ΓΌnΓ―\":\"π\"}").expect("nested object"),
1481 ]
1482 }
1483
1484 #[test]
1485 #[cfg(feature = "serde-json")]
1486 fn parse_of_to_json_string_reproduces_the_value() {
1487 for j in round_trip_corpus() {
1488 let encoded = j.to_json_string();
1489 let decoded = Json::parse(encoded.as_str())
1490 .unwrap_or_else(|e| panic!("{encoded:?} must re-parse: {e}"));
1491 assert_eq!(decoded, j, "round trip failed for {encoded:?}");
1492 }
1493 }
1494
1495 #[test]
1496 #[cfg(feature = "serde-json")]
1497 fn serialize_parse_serialize_is_idempotent() {
1498 for j in round_trip_corpus() {
1499 let once = j.to_json_string();
1500 let twice = Json::parse(once.as_str()).expect("re-parse").to_json_string();
1501 assert_eq!(once.as_str(), twice.as_str());
1502 }
1503 }
1504
1505 #[test]
1506 #[cfg(feature = "serde-json")]
1507 fn round_trip_extreme_floats() {
1508 for n in [f64::MAX, f64::MIN, f64::MIN_POSITIVE, -f64::MIN_POSITIVE] {
1509 let j = Json::number(n);
1510 let encoded = j.to_json_string();
1511 let decoded = Json::parse(encoded.as_str())
1512 .unwrap_or_else(|e| panic!("{encoded:?} must re-parse: {e}"));
1513 assert_eq!(decoded.as_number(), OptionF64::Some(n));
1514 }
1515 }
1516
1517 #[test]
1518 #[cfg(feature = "serde-json")]
1519 fn non_finite_numbers_do_not_survive_to_json_string() {
1520 for (n, token) in [
1527 (f64::NAN, "NaN"),
1528 (f64::INFINITY, "inf"),
1529 (f64::NEG_INFINITY, "-inf"),
1530 ] {
1531 let j = Json::number(n);
1532 let encoded = j.to_json_string();
1533 assert_eq!(encoded.as_str(), token);
1534 assert!(
1535 Json::parse(encoded.as_str()).is_err(),
1536 "{token} is not valid JSON"
1537 );
1538 assert_eq!(j.to_serde_value(), serde_json::Value::Null);
1540 }
1541 }
1542
1543 #[test]
1548 #[cfg(feature = "serde-json")]
1549 fn from_serde_value_maps_every_variant() {
1550 use serde_json::json;
1551
1552 assert!(Json::from_serde_value(json!(null)).is_null());
1553 assert_eq!(
1554 Json::from_serde_value(json!(true)).as_bool(),
1555 OptionBool::Some(true)
1556 );
1557 assert_eq!(
1558 Json::from_serde_value(json!(-3)).as_i64(),
1559 OptionI64::Some(-3)
1560 );
1561 assert_eq!(
1562 Json::from_serde_value(json!("π")).as_string(),
1563 OptionString::Some(az("π"))
1564 );
1565
1566 let arr = Json::from_serde_value(json!([1, "two", null]));
1567 assert!(arr.is_array());
1568 assert_eq!(arr.len(), 3);
1569 assert_eq!(arr.get_index(1).expect("idx 1"), Json::string("two"));
1570
1571 let obj = Json::from_serde_value(json!({"a": 1, "b": {"c": []}}));
1572 assert!(obj.is_object());
1573 assert_eq!(obj.len(), 2);
1574 assert_eq!(obj.get_key("a").expect("a"), Json::integer(1));
1575 assert!(Json::parse(obj.raw_string()).is_ok());
1577 }
1578
1579 #[test]
1580 #[cfg(feature = "serde-json")]
1581 fn to_serde_value_round_trips_through_from_serde_value() {
1582 use serde_json::json;
1583
1584 for v in [
1585 json!(null),
1586 json!(false),
1587 json!(0),
1588 json!(-1.5),
1589 json!(""),
1590 json!([]),
1591 json!({}),
1592 json!({"k": [1, {"n": null}], "ΓΌ": "π"}),
1593 ] {
1594 let back = Json::from_serde_value(v.clone()).to_serde_value();
1595 assert_eq!(back, v);
1596 }
1597 }
1598
1599 #[test]
1600 #[cfg(feature = "serde-json")]
1601 fn to_serde_value_on_a_corrupt_container_yields_null() {
1602 assert_eq!(
1603 raw(JsonType::Array, "not json").to_serde_value(),
1604 serde_json::Value::Null
1605 );
1606 assert_eq!(
1607 raw(JsonType::Object, "").to_serde_value(),
1608 serde_json::Value::Null
1609 );
1610 }
1611
1612 #[test]
1617 #[cfg(feature = "serde-json")]
1618 fn array_constructor_handles_empty_and_non_finite_members() {
1619 let empty = Json::array(JsonVec::new());
1620 assert!(empty.is_array());
1621 assert_eq!(empty.len(), 0);
1622 assert!(empty.is_empty());
1623 assert_eq!(empty.raw_string(), "[]");
1624
1625 let with_nan = Json::array(JsonVec::from_vec(vec![
1628 Json::number(f64::NAN),
1629 Json::number(f64::INFINITY),
1630 Json::integer(1),
1631 ]));
1632 assert_eq!(with_nan.raw_string(), "[null,null,1]");
1633 assert_eq!(with_nan.len(), 3);
1634 assert!(Json::parse(with_nan.raw_string()).is_ok());
1635 }
1636
1637 #[test]
1638 #[cfg(feature = "serde-json")]
1639 fn object_constructor_dedupes_duplicate_keys_last_one_wins() {
1640 let empty = Json::object(JsonKeyValueVec::new());
1641 assert!(empty.is_object());
1642 assert!(empty.is_empty());
1643 assert_eq!(empty.raw_string(), "{}");
1644
1645 let dup = Json::object(JsonKeyValueVec::from_vec(vec![
1646 JsonKeyValue::create(az("k"), Json::integer(1)),
1647 JsonKeyValue::create(az("k"), Json::integer(2)),
1648 JsonKeyValue::create(az(""), Json::null()),
1649 ]));
1650 assert_eq!(dup.len(), 2, "duplicate keys collapse into one entry");
1651 assert_eq!(dup.get_key("k").expect("k"), Json::integer(2));
1652 assert!(dup.get_key("").expect("empty key").is_null());
1653 }
1654
1655 #[test]
1656 #[cfg(feature = "serde-json")]
1657 fn object_constructor_escapes_hostile_keys() {
1658 let obj = Json::object(JsonKeyValueVec::from_vec(vec![JsonKeyValue::create(
1659 az("\"}\nπ"),
1660 Json::string("v"),
1661 )]));
1662 let reparsed = Json::parse(obj.raw_string()).expect("hostile key must be escaped");
1664 assert_eq!(
1665 reparsed.get_key("\"}\nπ").expect("key").as_string(),
1666 OptionString::Some(az("v"))
1667 );
1668 }
1669
1670 #[test]
1675 #[cfg(feature = "serde-json")]
1676 fn len_is_zero_for_scalars_which_makes_is_empty_true() {
1677 for j in [
1680 Json::null(),
1681 Json::bool(true),
1682 Json::integer(7),
1683 Json::string("hello"),
1684 ] {
1685 assert_eq!(j.len(), 0);
1686 assert!(j.is_empty());
1687 }
1688 }
1689
1690 #[test]
1691 #[cfg(feature = "serde-json")]
1692 fn len_of_containers_and_corrupt_payloads() {
1693 assert_eq!(Json::parse("[1,2,3]").expect("arr").len(), 3);
1694 assert_eq!(Json::parse("{\"a\":1}").expect("obj").len(), 1);
1695 assert_eq!(Json::parse("[]").expect("[]").len(), 0);
1696 assert_eq!(raw(JsonType::Array, "not json").len(), 0);
1698 assert!(raw(JsonType::Object, "").is_empty());
1699 assert_eq!(raw(JsonType::Array, "{\"a\":1}").len(), 0);
1701 }
1702
1703 #[test]
1708 #[cfg(feature = "serde-json")]
1709 fn get_index_boundaries() {
1710 let arr = Json::parse("[10,20]").expect("arr");
1711 assert_eq!(arr.get_index(0).expect("0"), Json::integer(10));
1712 assert_eq!(arr.get_index(1).expect("1"), Json::integer(20));
1713 assert!(arr.get_index(2).is_none());
1714 assert!(arr.get_index(usize::MAX).is_none());
1715
1716 assert!(Json::parse("[]").expect("[]").get_index(0).is_none());
1717 assert!(Json::parse("{\"0\":1}").expect("obj").get_index(0).is_none());
1719 assert!(Json::string("abc").get_index(0).is_none());
1720 assert!(raw(JsonType::Array, "not json").get_index(0).is_none());
1721 assert!(raw(JsonType::Array, "{\"a\":1}").get_index(0).is_none());
1722 }
1723
1724 #[test]
1725 #[cfg(feature = "serde-json")]
1726 fn get_key_edge_inputs() {
1727 let obj = Json::parse("{\"\":1,\"a\":null,\"π\":[]}").expect("obj");
1728 assert_eq!(obj.get_key("").expect("empty key"), Json::integer(1));
1729 assert!(obj.get_key("a").expect("a").is_null());
1730 assert!(obj.get_key("π").expect("emoji").is_array());
1731 assert!(obj.get_key("missing").is_none());
1732 assert!(obj.get_key(" a").is_none());
1734 assert!(obj.get_key("A").is_none());
1735 assert!(obj.get_key(&"k".repeat(1_000_000)).is_none());
1737 assert!(Json::parse("[1]").expect("arr").get_key("0").is_none());
1739 assert!(Json::null().get_key("").is_none());
1740 assert!(raw(JsonType::Object, "not json").get_key("a").is_none());
1741 }
1742
1743 #[test]
1744 #[cfg(feature = "serde-json")]
1745 fn keys_returns_every_key_and_nothing_for_non_objects() {
1746 let obj = Json::parse("{\"b\":1,\"a\":2,\"\":3}").expect("obj");
1747 let keys = obj.keys();
1748 assert_eq!(keys.len(), 3);
1749 for expected in ["a", "b", ""] {
1750 assert!(
1751 keys.iter().any(|k| k.as_str() == expected),
1752 "missing key {expected:?}"
1753 );
1754 }
1755 assert!(Json::parse("{}").expect("{}").keys().is_empty());
1756 assert!(Json::parse("[1,2]").expect("arr").keys().is_empty());
1757 assert!(Json::string("x").keys().is_empty());
1758 assert!(raw(JsonType::Object, "not json").keys().is_empty());
1759 }
1760
1761 #[test]
1762 #[cfg(feature = "serde-json")]
1763 fn to_array_and_to_object_on_wrong_types_and_corrupt_payloads() {
1764 let arr = Json::parse("[null,1]").expect("arr").to_array().expect("to_array");
1765 assert_eq!(arr.len(), 2);
1766 assert!(arr.as_slice()[0].is_null());
1767 assert_eq!(arr.as_slice()[1].as_i64(), OptionI64::Some(1));
1768
1769 let obj = Json::parse("{\"a\":\"v\"}").expect("obj").to_object().expect("to_object");
1770 assert_eq!(obj.len(), 1);
1771 assert_eq!(obj.as_slice()[0].key.as_str(), "a");
1772 assert_eq!(
1773 obj.as_slice()[0].value.as_string(),
1774 OptionString::Some(az("v"))
1775 );
1776
1777 assert!(Json::parse("[]").expect("[]").to_array().expect("empty").is_empty());
1778 assert!(Json::parse("{}").expect("{}").to_object().expect("empty").is_empty());
1779
1780 assert!(Json::null().to_array().is_none());
1782 assert!(Json::string("[]").to_array().is_none());
1783 assert!(Json::parse("[]").expect("[]").to_object().is_none());
1784 assert!(raw(JsonType::Array, "not json").to_array().is_none());
1785 assert!(raw(JsonType::Object, "").to_object().is_none());
1786 assert!(raw(JsonType::Array, "{\"a\":1}").to_array().is_none());
1787 assert!(raw(JsonType::Object, "[1]").to_object().is_none());
1788 }
1789
1790 #[test]
1795 #[cfg(feature = "serde-json")]
1796 fn to_json_string_escapes_strings_unlike_display() {
1797 let j = Json::string("a\"b\nc\\d\u{0}");
1798 let encoded = j.to_json_string();
1799 assert_eq!(Json::parse(encoded.as_str()).expect("escaped"), j);
1801 assert_ne!(encoded.as_str(), alloc::format!("{j}"));
1803 }
1804
1805 #[test]
1806 #[cfg(feature = "serde-json")]
1807 fn to_string_pretty_matches_to_json_string_for_scalars() {
1808 for j in [
1809 Json::null(),
1810 Json::bool(false),
1811 Json::integer(-7),
1812 Json::number(0.5),
1813 Json::string("π"),
1814 ] {
1815 assert_eq!(j.to_string_pretty().as_str(), j.to_json_string().as_str());
1816 }
1817 }
1818
1819 #[test]
1820 #[cfg(feature = "serde-json")]
1821 fn to_string_pretty_of_containers_reparses_to_the_same_value() {
1822 let j = Json::parse("{\"a\":[1,{\"b\":null}],\"c\":{}}").expect("obj");
1823 let pretty = j.to_string_pretty();
1824 assert!(pretty.as_str().contains('\n'), "pretty output must be indented");
1825 assert_eq!(Json::parse(pretty.as_str()).expect("pretty reparses"), j);
1826
1827 let corrupt = raw(JsonType::Object, "not json");
1829 assert_eq!(corrupt.to_string_pretty().as_str(), "not json");
1830 assert_eq!(raw(JsonType::Array, "").to_string_pretty().as_str(), "");
1831 }
1832
1833 #[test]
1838 #[cfg(feature = "serde-json")]
1839 fn jq_on_scalars_only_matches_the_empty_pointer() {
1840 for j in [
1841 Json::null(),
1842 Json::bool(true),
1843 Json::integer(1),
1844 Json::string("s"),
1845 ] {
1846 assert_eq!(j.jq(""), j);
1847 assert!(j.jq("/").is_null());
1848 assert!(j.jq("/a").is_null());
1849 assert!(j.jq("nonsense").is_null());
1850 assert_eq!(j.jq_all("").as_ref().len(), 1);
1851 assert_eq!(j.jq_all("/a").as_ref().len(), 0);
1852 }
1853 }
1854
1855 #[test]
1856 #[cfg(feature = "serde-json")]
1857 fn jq_navigates_and_degrades_to_null() {
1858 let j = Json::parse("{\"a\":{\"b\":[10,20]},\"\":1}").expect("doc");
1859 assert_eq!(j.jq(""), j, "the empty pointer selects the whole document");
1860 assert_eq!(j.jq("/a/b/1"), Json::integer(20));
1861 assert_eq!(j.jq("/"), Json::integer(1), "'/' selects the empty-string key");
1862
1863 assert!(j.jq("/a/b/2").is_null(), "out-of-range index");
1865 assert!(j.jq("/a/b/-1").is_null(), "negative index is not a usize");
1866 assert!(j.jq("/a/b/99999999999999999999").is_null(), "index overflows usize");
1867 assert!(j.jq("a/b").is_null(), "pointer must start with '/'");
1868 assert!(j.jq("/missing").is_null());
1869 assert!(j.jq(&"/a".repeat(100_000)).is_null(), "huge pointer");
1870 assert!(j.jq("/a/b/1/deeper").is_null(), "descending through a scalar");
1871 assert!(raw(JsonType::Object, "not json").jq("/a").is_null());
1872 }
1873
1874 #[test]
1875 #[cfg(feature = "serde-json")]
1876 fn jq_all_wildcards_and_empty_results() {
1877 let j = Json::parse("{\"a\":[{\"v\":1},{\"v\":2}],\"b\":{\"v\":3},\"c\":7}").expect("doc");
1878
1879 assert_eq!(j.jq_all("/a/*/v").as_ref().len(), 2);
1880 assert_eq!(j.jq_all("/*/v").as_ref().len(), 1);
1882 assert_eq!(j.jq_all("/*").as_ref().len(), 3);
1883 assert_eq!(j.jq_all("").as_ref().len(), 1);
1884
1885 assert_eq!(j.jq_all("/missing/*").as_ref().len(), 0);
1887 assert_eq!(j.jq_all("a").as_ref().len(), 0);
1888 assert_eq!(j.jq_all("/c/*").as_ref().len(), 0, "wildcard over a scalar");
1889 assert_eq!(j.jq_all("/*/*/*/*/*").as_ref().len(), 0);
1890 assert_eq!(
1891 raw(JsonType::Array, "not json").jq_all("/*").as_ref().len(),
1892 0
1893 );
1894
1895 let many = "/*".repeat(10_000);
1897 assert_eq!(j.jq_all(&many).as_ref().len(), 0);
1898 }
1899
1900 #[test]
1905 #[cfg(feature = "serde-json")]
1906 fn jq_all_recursive_depth_honours_the_wildcard_cap() {
1907 let value = serde_json::json!({"a": 1});
1908
1909 assert_eq!(Json::jq_all_recursive_depth(&value, "/a", 0).len(), 1);
1911 assert_eq!(
1913 Json::jq_all_recursive_depth(&value, "/a", Json::JQ_MAX_WILDCARD_DEPTH).len(),
1914 1
1915 );
1916 assert_eq!(
1918 Json::jq_all_recursive_depth(&value, "/a", Json::JQ_MAX_WILDCARD_DEPTH + 1).len(),
1919 0
1920 );
1921 assert_eq!(Json::jq_all_recursive_depth(&value, "/*", usize::MAX).len(), 0);
1924 assert_eq!(Json::jq_all_recursive_depth(&value, "", usize::MAX).len(), 0);
1925 }
1926
1927 #[test]
1928 #[cfg(feature = "serde-json")]
1929 fn jq_all_wildcard_fanout_deeper_than_the_cap_returns_empty() {
1930 fn nest(depth: usize) -> serde_json::Value {
1934 let mut v = serde_json::Value::from(1_i64);
1935 for _ in 0..depth {
1936 v = serde_json::Value::Array(vec![v]);
1937 }
1938 v
1939 }
1940
1941 let shallow = nest(400);
1943 let found = Json::jq_all_recursive(&shallow, &"/*".repeat(400));
1944 assert_eq!(found.len(), 1);
1945 assert_eq!(found[0].as_i64(), OptionI64::Some(1));
1946
1947 let deep = nest(600);
1949 assert!(Json::jq_all_recursive(&deep, &"/*".repeat(600)).is_empty());
1950 }
1951}