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 JsonInternal {
50 fn default() -> Self {
51 Self {
52 string_value: AzString::from(String::new()),
53 number_value: 0.0,
54 bool_value: false,
55 }
56 }
57}
58
59#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61#[repr(C)]
62pub enum JsonType {
63 Null,
65 Bool,
67 Number,
69 String,
71 Array,
73 Object,
75}
76
77#[derive(Debug, Clone, PartialEq, Eq)]
79#[repr(C)]
80pub struct JsonParseError {
81 pub message: AzString,
83 pub line: u32,
85 pub column: u32,
87}
88
89impl fmt::Display for JsonParseError {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 if self.line > 0 {
92 write!(f, "{}:{}: {}", self.line, self.column, self.message.as_str())
93 } else {
94 write!(f, "{}", self.message.as_str())
95 }
96 }
97}
98
99#[cfg(feature = "std")]
100impl std::error::Error for JsonParseError {}
101
102#[derive(Debug, Clone, PartialEq)]
104#[repr(C)]
105pub struct JsonKeyValue {
106 pub key: AzString,
108 pub value: Json,
110}
111
112impl JsonKeyValue {
113 #[must_use] pub const fn create(key: AzString, value: Json) -> Self {
115 Self { key, value }
116 }
117}
118
119impl_option!(JsonKeyValue, OptionJsonKeyValue, copy = false, [Debug, Clone, PartialEq]);
125
126impl_vec!(JsonKeyValue, JsonKeyValueVec, JsonKeyValueVecDestructor, JsonKeyValueVecDestructorType, JsonKeyValueVecSlice, OptionJsonKeyValue);
128impl_vec_clone!(JsonKeyValue, JsonKeyValueVec, JsonKeyValueVecDestructor);
129impl_vec_debug!(JsonKeyValue, JsonKeyValueVec);
130
131impl JsonKeyValueVec {
132 #[inline]
134 #[allow(clippy::not_unsafe_ptr_arg_deref)] #[must_use] pub fn copy_from_array(ptr: *const JsonKeyValue, len: usize) -> Self {
136 if ptr.is_null() || len == 0 {
137 return Self::new();
138 }
139 let slice = unsafe { core::slice::from_raw_parts(ptr, len) };
140 Self::from_vec(slice.to_vec())
141 }
142}
143
144impl_vec!(Json, JsonVec, JsonVecDestructor, JsonVecDestructorType, JsonVecSlice, OptionJson);
146impl_vec_clone!(Json, JsonVec, JsonVecDestructor);
147impl_vec_debug!(Json, JsonVec);
148impl_vec_partialeq!(Json, JsonVec);
149impl_vec_mut!(Json, JsonVec);
150
151impl JsonVec {
152 #[inline]
154 #[allow(clippy::not_unsafe_ptr_arg_deref)] #[must_use] pub fn copy_from_array(ptr: *const Json, len: usize) -> Self {
156 if ptr.is_null() || len == 0 {
157 return Self::new();
158 }
159 let slice = unsafe { core::slice::from_raw_parts(ptr, len) };
160 Self::from_vec(slice.to_vec())
161 }
162}
163
164impl_result!(
166 Json,
167 JsonParseError,
168 ResultJsonJsonParseError,
169 copy = false,
170 [Debug, Clone, PartialEq]
171);
172
173impl_option!(Json, OptionJson, copy = false, [Clone, Debug, PartialEq]);
175impl_option!(JsonVec, OptionJsonVec, copy = false, [Clone, Debug]);
176impl_option!(JsonKeyValueVec, OptionJsonKeyValueVec, copy = false, [Clone, Debug]);
177
178impl_option!(i64, OptionI64, [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]);
181
182#[allow(clippy::cast_possible_truncation)] fn f64_as_i64(n: f64) -> Option<i64> {
194 if n.fract() == 0.0 && n >= -(2_f64.powi(63)) && n < 2_f64.powi(63) {
195 Some(n as i64)
196 } else {
197 None
198 }
199}
200
201impl Json {
206 #[must_use] pub fn null() -> Self {
208 Self {
209 value_type: JsonType::Null,
210 internal: JsonInternal::default(),
211 }
212 }
213
214 #[must_use] pub fn bool(value: bool) -> Self {
216 Self {
217 value_type: JsonType::Bool,
218 internal: JsonInternal {
219 string_value: AzString::from(String::new()),
220 number_value: 0.0,
221 bool_value: value,
222 },
223 }
224 }
225
226 #[must_use] pub fn number(value: f64) -> Self {
228 Self {
229 value_type: JsonType::Number,
230 internal: JsonInternal {
231 string_value: AzString::from(String::new()),
232 number_value: value,
233 bool_value: false,
234 },
235 }
236 }
237
238 #[allow(clippy::cast_precision_loss)] #[must_use] pub fn integer(value: i64) -> Self {
244 Self {
245 value_type: JsonType::Number,
246 internal: JsonInternal {
247 string_value: AzString::from(String::new()),
248 number_value: value as f64,
249 bool_value: false,
250 },
251 }
252 }
253
254 pub fn string(value: impl Into<String>) -> Self {
256 Self {
257 value_type: JsonType::String,
258 internal: JsonInternal {
259 string_value: AzString::from(value.into()),
260 number_value: 0.0,
261 bool_value: false,
262 },
263 }
264 }
265
266 #[must_use] pub fn is_null(&self) -> bool {
268 self.value_type == JsonType::Null
269 }
270
271 #[must_use] pub fn is_bool(&self) -> bool {
273 self.value_type == JsonType::Bool
274 }
275
276 #[must_use] pub fn is_number(&self) -> bool {
278 self.value_type == JsonType::Number
279 }
280
281 #[must_use] pub fn is_string(&self) -> bool {
283 self.value_type == JsonType::String
284 }
285
286 #[must_use] pub fn is_array(&self) -> bool {
288 self.value_type == JsonType::Array
289 }
290
291 #[must_use] pub fn is_object(&self) -> bool {
293 self.value_type == JsonType::Object
294 }
295
296 #[must_use] pub fn as_bool(&self) -> OptionBool {
298 if self.value_type == JsonType::Bool {
299 OptionBool::Some(self.internal.bool_value)
300 } else {
301 OptionBool::None
302 }
303 }
304
305 #[must_use] pub fn as_number(&self) -> OptionF64 {
307 if self.value_type == JsonType::Number {
308 OptionF64::Some(self.internal.number_value)
309 } else {
310 OptionF64::None
311 }
312 }
313
314 #[must_use] pub fn as_i64(&self) -> OptionI64 {
316 if self.value_type == JsonType::Number {
317 f64_as_i64(self.internal.number_value).map_or(OptionI64::None, OptionI64::Some)
318 } else {
319 OptionI64::None
320 }
321 }
322
323 #[must_use] pub fn as_string(&self) -> OptionString {
325 if self.value_type == JsonType::String {
326 OptionString::Some(self.internal.string_value.clone())
327 } else {
328 OptionString::None
329 }
330 }
331
332 #[must_use] pub fn raw_string(&self) -> &str {
334 self.internal.string_value.as_str()
335 }
336}
337
338impl fmt::Display for Json {
343 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
344 match self.value_type {
345 JsonType::Null => write!(f, "null"),
346 JsonType::Bool => write!(f, "{}", self.internal.bool_value),
347 JsonType::Number => {
348 let num = self.internal.number_value;
349 if let Some(i) = f64_as_i64(num) {
350 write!(f, "{i}")
351 } else {
352 write!(f, "{num}")
353 }
354 }
355 JsonType::String => write!(f, "\"{}\"", self.internal.string_value.as_str()),
356 JsonType::Array | JsonType::Object => {
357 write!(f, "{}", self.internal.string_value.as_str())
358 }
359 }
360 }
361}
362
363#[cfg(feature = "serde-json")]
368impl Json {
369 pub fn parse(s: &str) -> Result<Self, JsonParseError> {
371 let value: serde_json::Value = serde_json::from_str(s).map_err(|e| {
372 JsonParseError {
373 message: AzString::from(alloc::format!("{}", e)),
374 line: e.line() as u32,
375 column: e.column() as u32,
376 }
377 })?;
378 Ok(Self::from_serde_value(value))
379 }
380
381 pub fn parse_bytes(bytes: &[u8]) -> Result<Self, JsonParseError> {
383 let value: serde_json::Value = serde_json::from_slice(bytes).map_err(|e| {
384 JsonParseError {
385 message: AzString::from(alloc::format!("{}", e)),
386 line: e.line() as u32,
387 column: e.column() as u32,
388 }
389 })?;
390 Ok(Self::from_serde_value(value))
391 }
392
393 pub fn from_serde_value(value: serde_json::Value) -> Self {
395 match value {
396 serde_json::Value::Null => Self::null(),
397 serde_json::Value::Bool(b) => Self::bool(b),
398 serde_json::Value::Number(n) => Self::number(n.as_f64().unwrap_or(0.0)),
399 serde_json::Value::String(s) => Self::string(s),
400 serde_json::Value::Array(arr) => {
401 let json_str = serde_json::to_string(&serde_json::Value::Array(arr)).unwrap_or_default();
402 Self {
403 value_type: JsonType::Array,
404 internal: JsonInternal {
405 string_value: AzString::from(json_str),
406 number_value: 0.0,
407 bool_value: false,
408 },
409 }
410 }
411 serde_json::Value::Object(obj) => {
412 let json_str = serde_json::to_string(&serde_json::Value::Object(obj)).unwrap_or_default();
413 Self {
414 value_type: JsonType::Object,
415 internal: JsonInternal {
416 string_value: AzString::from(json_str),
417 number_value: 0.0,
418 bool_value: false,
419 },
420 }
421 }
422 }
423 }
424
425 pub fn to_serde_value(&self) -> serde_json::Value {
427 match self.value_type {
428 JsonType::Null => serde_json::Value::Null,
429 JsonType::Bool => serde_json::Value::Bool(self.internal.bool_value),
430 JsonType::Number => {
431 let num = self.internal.number_value;
432 if let Some(i) = f64_as_i64(num) {
433 serde_json::Value::Number(serde_json::Number::from(i))
434 } else {
435 serde_json::Number::from_f64(num)
436 .map(serde_json::Value::Number)
437 .unwrap_or(serde_json::Value::Null)
438 }
439 }
440 JsonType::String => serde_json::Value::String(self.internal.string_value.as_str().to_string()),
441 JsonType::Array | JsonType::Object => {
442 serde_json::from_str(self.internal.string_value.as_str())
443 .unwrap_or(serde_json::Value::Null)
444 }
445 }
446 }
447
448 pub fn array(values: JsonVec) -> Self {
450 let serde_array: Vec<serde_json::Value> = values
451 .as_slice()
452 .iter()
453 .map(|j| j.to_serde_value())
454 .collect();
455 let json_str = serde_json::to_string(&serde_json::Value::Array(serde_array))
456 .unwrap_or_else(|_| "[]".to_string());
457 Self {
458 value_type: JsonType::Array,
459 internal: JsonInternal {
460 string_value: AzString::from(json_str),
461 number_value: 0.0,
462 bool_value: false,
463 },
464 }
465 }
466
467 pub fn object(entries: JsonKeyValueVec) -> Self {
469 let mut map = serde_json::Map::new();
470 for kv in entries.as_slice() {
471 map.insert(kv.key.as_str().to_string(), kv.value.to_serde_value());
472 }
473 let json_str = serde_json::to_string(&serde_json::Value::Object(map))
474 .unwrap_or_else(|_| "{}".to_string());
475 Self {
476 value_type: JsonType::Object,
477 internal: JsonInternal {
478 string_value: AzString::from(json_str),
479 number_value: 0.0,
480 bool_value: false,
481 },
482 }
483 }
484
485 pub fn len(&self) -> usize {
487 match self.value_type {
488 JsonType::Array => {
489 if let Ok(serde_json::Value::Array(arr)) = serde_json::from_str(self.internal.string_value.as_str()) {
490 arr.len()
491 } else {
492 0
493 }
494 }
495 JsonType::Object => {
496 if let Ok(serde_json::Value::Object(obj)) = serde_json::from_str(self.internal.string_value.as_str()) {
497 obj.len()
498 } else {
499 0
500 }
501 }
502 _ => 0,
503 }
504 }
505
506 pub fn is_empty(&self) -> bool {
508 self.len() == 0
509 }
510
511 pub fn get_index(&self, index: usize) -> Option<Json> {
513 if self.value_type != JsonType::Array { return None; }
514 let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
515 if let serde_json::Value::Array(arr) = value {
516 arr.get(index).map(|v| Self::from_serde_value(v.clone()))
517 } else {
518 None
519 }
520 }
521
522 pub fn get_key(&self, key: &str) -> Option<Json> {
524 if self.value_type != JsonType::Object { return None; }
525 let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
526 if let serde_json::Value::Object(obj) = value {
527 obj.get(key).map(|v| Self::from_serde_value(v.clone()))
528 } else {
529 None
530 }
531 }
532
533 pub fn keys(&self) -> Vec<AzString> {
535 if self.value_type != JsonType::Object { return Vec::new(); }
536 let value: serde_json::Value = match serde_json::from_str(self.internal.string_value.as_str()) {
537 Ok(v) => v,
538 Err(_) => return Vec::new(),
539 };
540 if let serde_json::Value::Object(obj) = value {
541 obj.keys().map(|k| AzString::from(k.clone())).collect()
542 } else {
543 Vec::new()
544 }
545 }
546
547 pub fn to_array(&self) -> Option<JsonVec> {
549 if self.value_type != JsonType::Array { return None; }
550 let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
551 if let serde_json::Value::Array(arr) = value {
552 Some(arr.into_iter().map(Self::from_serde_value).collect())
553 } else {
554 None
555 }
556 }
557
558 pub fn to_object(&self) -> Option<JsonKeyValueVec> {
560 if self.value_type != JsonType::Object { return None; }
561 let value: serde_json::Value = serde_json::from_str(self.internal.string_value.as_str()).ok()?;
562 if let serde_json::Value::Object(obj) = value {
563 Some(obj.into_iter().map(|(k, v)| JsonKeyValue {
564 key: AzString::from(k),
565 value: Self::from_serde_value(v),
566 }).collect())
567 } else {
568 None
569 }
570 }
571
572 pub fn to_json_string(&self) -> AzString {
574 match self.value_type {
575 JsonType::Null => AzString::from(alloc::string::String::from("null")),
576 JsonType::Bool => AzString::from(if self.internal.bool_value { alloc::string::String::from("true") } else { alloc::string::String::from("false") }),
577 JsonType::Number => {
578 let num = self.internal.number_value;
579 if let Some(i) = f64_as_i64(num) {
580 AzString::from(alloc::format!("{}", i))
581 } else {
582 AzString::from(alloc::format!("{}", num))
583 }
584 }
585 JsonType::String => {
586 let escaped = serde_json::to_string(self.internal.string_value.as_str()).unwrap_or_default();
587 AzString::from(escaped)
588 }
589 JsonType::Array | JsonType::Object => {
590 self.internal.string_value.clone()
591 }
592 }
593 }
594
595 pub fn to_string_pretty(&self) -> AzString {
597 match self.value_type {
598 JsonType::Null | JsonType::Bool | JsonType::Number | JsonType::String => {
599 self.to_json_string()
600 }
601 JsonType::Array | JsonType::Object => {
602 if let Ok(value) = serde_json::from_str::<serde_json::Value>(self.internal.string_value.as_str()) {
603 AzString::from(serde_json::to_string_pretty(&value).unwrap_or_default())
604 } else {
605 self.internal.string_value.clone()
606 }
607 }
608 }
609 }
610
611 pub fn jq(&self, path: &str) -> Json {
613 match self.value_type {
614 JsonType::Null | JsonType::Bool | JsonType::Number | JsonType::String => {
615 if path.is_empty() { self.clone() } else { Json::null() }
616 }
617 JsonType::Array | JsonType::Object => {
618 let value: serde_json::Value = match serde_json::from_str(self.internal.string_value.as_str()) {
619 Ok(v) => v,
620 Err(_) => return Json::null(),
621 };
622 match value.pointer(path) {
623 Some(v) => Self::from_serde_value(v.clone()),
624 None => Json::null(),
625 }
626 }
627 }
628 }
629
630 pub fn jq_all(&self, path: &str) -> JsonVec {
632 let result = match self.value_type {
633 JsonType::Null | JsonType::Bool | JsonType::Number | JsonType::String => {
634 if path.is_empty() { vec![self.clone()] } else { vec![] }
635 }
636 JsonType::Array | JsonType::Object => {
637 let value: serde_json::Value = match serde_json::from_str(self.internal.string_value.as_str()) {
638 Ok(v) => v,
639 Err(_) => return JsonVec::from_vec(vec![]),
640 };
641 Self::jq_all_recursive(&value, path)
642 }
643 };
644 JsonVec::from_vec(result)
645 }
646
647 const JQ_MAX_WILDCARD_DEPTH: usize = 512;
656
657 fn jq_all_recursive(value: &serde_json::Value, path: &str) -> Vec<Json> {
663 Self::jq_all_recursive_depth(value, path, 0)
664 }
665
666 fn jq_all_recursive_depth(
667 value: &serde_json::Value,
668 path: &str,
669 depth: usize,
670 ) -> Vec<Json> {
671 if depth > Self::JQ_MAX_WILDCARD_DEPTH {
674 return vec![];
675 }
676
677 let mut value = value;
679 let mut path = path;
680 loop {
681 if path.is_empty() {
682 return vec![Self::from_serde_value(value.clone())];
683 }
684 if !path.starts_with('/') {
685 return vec![];
686 }
687 let rest = &path[1..];
688 let (component, remaining) = match rest.find('/') {
689 Some(idx) => (&rest[..idx], &rest[idx..]),
690 None => (rest, ""),
691 };
692
693 if component == "*" {
694 let mut results = Vec::new();
695 match value {
696 serde_json::Value::Array(arr) => {
697 for item in arr {
698 results.extend(Self::jq_all_recursive_depth(
699 item,
700 remaining,
701 depth + 1,
702 ));
703 }
704 }
705 serde_json::Value::Object(obj) => {
706 for (_key, val) in obj {
707 results.extend(Self::jq_all_recursive_depth(
708 val,
709 remaining,
710 depth + 1,
711 ));
712 }
713 }
714 _ => {}
715 }
716 return results;
717 }
718
719 let next = match value {
721 serde_json::Value::Array(arr) => {
722 component.parse::<usize>().ok().and_then(|idx| arr.get(idx))
723 }
724 serde_json::Value::Object(obj) => obj.get(component),
725 _ => None,
726 };
727 match next {
728 Some(v) => {
729 value = v;
730 path = remaining;
731 }
732 None => return vec![],
733 }
734 }
735 }
736}
737
738#[cfg(test)]
739mod jq_recursion_tests {
740 use super::*;
741
742 #[test]
749 #[cfg(feature = "serde-json")]
750 fn huge_pointer_on_shallow_doc_returns_empty() {
751 let json = Json::parse("{\"a\":{\"b\":1}}").expect("parse");
752 let pointer = "/a".repeat(200_000);
753 assert_eq!(json.jq_all(&pointer).as_ref().len(), 0);
754 }
755
756 #[test]
759 #[cfg(feature = "serde-json")]
760 fn deep_linear_pointer_resolves_leaf() {
761 const DEPTH: usize = 100; let mut doc = String::new();
764 for _ in 0..DEPTH {
765 doc.push_str("{\"a\":");
766 }
767 doc.push_str("42");
768 for _ in 0..DEPTH {
769 doc.push('}');
770 }
771
772 let json = Json::parse(&doc).expect("deep doc should parse");
773 let pointer = "/a".repeat(DEPTH);
774 let out = json.jq_all(&pointer);
775 assert_eq!(out.as_ref().len(), 1, "the single leaf should be found");
776 }
777
778 #[test]
780 #[cfg(feature = "serde-json")]
781 fn wildcard_and_index_still_work() {
782 let json = Json::parse("{\"items\":[{\"v\":1},{\"v\":2},{\"v\":3}]}").expect("parse");
783 let all = json.jq_all("/items/*/v");
784 assert_eq!(all.as_ref().len(), 3);
785 let one = json.jq_all("/items/1/v");
786 assert_eq!(one.as_ref().len(), 1);
787 }
788}
789
790#[cfg(test)]
791#[allow(clippy::float_cmp, clippy::unreadable_literal)]
792mod autotest_generated {
793 use super::*;
794
795 fn az(s: &str) -> AzString {
800 AzString::from(String::from(s))
801 }
802
803 fn raw(value_type: JsonType, string_value: &str) -> Json {
808 Json {
809 value_type,
810 internal: JsonInternal {
811 string_value: az(string_value),
812 number_value: 0.0,
813 bool_value: false,
814 },
815 }
816 }
817
818 fn two_pow_63() -> f64 {
819 2_f64.powi(63)
820 }
821
822 #[test]
827 fn f64_as_i64_zero_and_negative_zero() {
828 assert_eq!(f64_as_i64(0.0), Some(0));
829 assert_eq!(f64_as_i64(-0.0), Some(0));
831 }
832
833 #[test]
834 fn f64_as_i64_min_max_boundaries() {
835 assert_eq!(f64_as_i64(-two_pow_63()), Some(i64::MIN));
837 assert_eq!(f64_as_i64(two_pow_63()), None);
839 #[allow(clippy::cast_precision_loss)]
842 let max_as_f64 = i64::MAX as f64;
843 assert_eq!(max_as_f64, two_pow_63());
844 assert_eq!(f64_as_i64(max_as_f64), None);
845 let just_below = two_pow_63() - 1024.0;
847 assert_eq!(f64_as_i64(just_below), Some(9_223_372_036_854_774_784));
848 }
849
850 #[test]
851 fn f64_as_i64_negatives_are_deterministic() {
852 assert_eq!(f64_as_i64(-1.0), Some(-1));
853 assert_eq!(f64_as_i64(-42.0), Some(-42));
854 assert_eq!(f64_as_i64(-0.5), None);
855 assert_eq!(f64_as_i64(-1.0 - f64::EPSILON), None);
856 assert_eq!(f64_as_i64(-two_pow_63() * (1.0 + f64::EPSILON)), None);
858 }
859
860 #[test]
861 fn f64_as_i64_overflow_inputs_return_none_not_a_wrapped_cast() {
862 for n in [
863 1e19_f64,
864 1e300_f64,
865 -1e300_f64,
866 f64::MAX,
867 f64::MIN,
868 two_pow_63() * 2.0,
869 ] {
870 assert_eq!(f64_as_i64(n), None, "{n} must not be cast to i64");
871 }
872 }
873
874 #[test]
875 fn f64_as_i64_nan_and_infinity_do_not_panic() {
876 assert_eq!(f64_as_i64(f64::NAN), None);
879 assert_eq!(f64_as_i64(f64::INFINITY), None);
880 assert_eq!(f64_as_i64(f64::NEG_INFINITY), None);
881 }
882
883 #[test]
884 fn f64_as_i64_fractional_and_subnormal_return_none() {
885 assert_eq!(f64_as_i64(0.5), None);
886 assert_eq!(f64_as_i64(f64::EPSILON), None);
887 assert_eq!(f64_as_i64(f64::MIN_POSITIVE), None);
888 assert_eq!(f64_as_i64(f64::from_bits(1)), None);
890 }
891
892 #[test]
897 fn number_stores_nan_and_infinity_without_panicking() {
898 for n in [f64::NAN, f64::INFINITY, f64::NEG_INFINITY] {
899 let j = Json::number(n);
900 assert!(j.is_number());
901 assert_eq!(j.as_i64(), OptionI64::None);
902 match j.as_number() {
903 OptionF64::Some(v) => assert_eq!(v.is_nan(), n.is_nan()),
904 OptionF64::None => panic!("as_number() must be Some for a Number"),
905 }
906 let s = alloc::format!("{j}");
908 assert!(!s.is_empty());
909 }
910 }
911
912 #[test]
913 fn number_min_max_and_zero() {
914 assert_eq!(Json::number(0.0).as_i64(), OptionI64::Some(0));
915 assert_eq!(Json::number(-0.0).as_i64(), OptionI64::Some(0));
916 assert_eq!(Json::number(f64::MAX).as_number(), OptionF64::Some(f64::MAX));
917 assert_eq!(Json::number(f64::MIN).as_number(), OptionF64::Some(f64::MIN));
918 assert_eq!(Json::number(f64::MAX).as_i64(), OptionI64::None);
920 }
921
922 #[test]
923 fn integer_min_round_trips_but_max_does_not() {
924 assert_eq!(Json::integer(i64::MIN).as_i64(), OptionI64::Some(i64::MIN));
926 assert_eq!(Json::integer(i64::MAX).as_i64(), OptionI64::None);
930 assert_eq!(
931 Json::integer(i64::MAX).as_number(),
932 OptionF64::Some(two_pow_63())
933 );
934 }
935
936 #[test]
937 fn integer_silently_loses_precision_above_2_pow_53() {
938 let boundary = 1_i64 << 53; assert_eq!(Json::integer(boundary).as_i64(), OptionI64::Some(boundary));
940 assert_eq!(
942 Json::integer(boundary + 1).as_i64(),
943 OptionI64::Some(boundary)
944 );
945 assert_eq!(Json::integer(0).as_i64(), OptionI64::Some(0));
946 assert_eq!(Json::integer(-1).as_i64(), OptionI64::Some(-1));
947 }
948
949 #[test]
954 fn predicates_are_mutually_exclusive_for_every_type() {
955 let cases = [
956 (Json::null(), JsonType::Null),
957 (Json::bool(false), JsonType::Bool),
958 (Json::number(f64::NAN), JsonType::Number),
959 (Json::integer(0), JsonType::Number),
960 (Json::string(""), JsonType::String),
961 (raw(JsonType::Array, "[]"), JsonType::Array),
962 (raw(JsonType::Object, "{}"), JsonType::Object),
963 ];
964 for (j, ty) in &cases {
965 let flags = [
966 j.is_null(),
967 j.is_bool(),
968 j.is_number(),
969 j.is_string(),
970 j.is_array(),
971 j.is_object(),
972 ];
973 assert_eq!(
974 flags.iter().filter(|b| **b).count(),
975 1,
976 "exactly one predicate must hold for {ty:?}"
977 );
978 assert_eq!(j.value_type, *ty);
979 }
980 }
981
982 #[test]
983 fn predicates_on_a_default_internal_do_not_panic() {
984 for ty in [
986 JsonType::Null,
987 JsonType::Bool,
988 JsonType::Number,
989 JsonType::String,
990 JsonType::Array,
991 JsonType::Object,
992 ] {
993 let j = Json {
994 value_type: ty,
995 internal: JsonInternal::default(),
996 };
997 assert_eq!(j.is_null(), ty == JsonType::Null);
998 assert_eq!(j.is_object(), ty == JsonType::Object);
999 assert_eq!(j.raw_string(), "");
1000 }
1001 }
1002
1003 #[test]
1004 fn bool_constructor_keeps_both_values() {
1005 assert_eq!(Json::bool(true).as_bool(), OptionBool::Some(true));
1006 assert_eq!(Json::bool(false).as_bool(), OptionBool::Some(false));
1007 assert_eq!(Json::bool(true).raw_string(), "");
1009 assert_eq!(Json::bool(true).as_number(), OptionF64::None);
1010 }
1011
1012 #[test]
1013 fn string_constructor_handles_empty_unicode_and_huge_inputs() {
1014 assert_eq!(Json::string("").as_string(), OptionString::Some(az("")));
1015
1016 let unicode = "π nÑïve \u{0301}\u{202e}\0 δΈζ";
1017 assert_eq!(
1018 Json::string(unicode).as_string(),
1019 OptionString::Some(az(unicode))
1020 );
1021 assert_eq!(Json::string(unicode).raw_string(), unicode);
1022
1023 let huge = "a".repeat(1_000_000);
1024 let j = Json::string(huge.clone());
1025 assert_eq!(j.raw_string().len(), 1_000_000);
1026 assert_eq!(j.as_string(), OptionString::Some(AzString::from(huge)));
1027 }
1028
1029 #[test]
1034 fn getters_return_none_on_type_mismatch() {
1035 let null = Json::null();
1036 assert_eq!(null.as_bool(), OptionBool::None);
1037 assert_eq!(null.as_number(), OptionF64::None);
1038 assert_eq!(null.as_i64(), OptionI64::None);
1039 assert_eq!(null.as_string(), OptionString::None);
1040
1041 let mut liar = Json::bool(true);
1044 liar.internal.number_value = 7.0;
1045 liar.internal.string_value = az("7");
1046 assert_eq!(liar.as_number(), OptionF64::None);
1047 assert_eq!(liar.as_i64(), OptionI64::None);
1048 assert_eq!(liar.as_string(), OptionString::None);
1049 assert_eq!(liar.as_bool(), OptionBool::Some(true));
1050 assert_eq!(liar.raw_string(), "7");
1052 }
1053
1054 #[test]
1055 fn raw_string_is_empty_for_scalars_and_serialized_for_containers() {
1056 assert_eq!(Json::null().raw_string(), "");
1057 assert_eq!(Json::bool(true).raw_string(), "");
1058 assert_eq!(Json::number(1.5).raw_string(), "");
1059 assert_eq!(Json::string("hi").raw_string(), "hi");
1060 assert_eq!(raw(JsonType::Array, "[1,2]").raw_string(), "[1,2]");
1061 assert_eq!(raw(JsonType::Object, "{not json").raw_string(), "{not json");
1063 }
1064
1065 #[test]
1070 fn display_scalar_values() {
1071 assert_eq!(alloc::format!("{}", Json::null()), "null");
1072 assert_eq!(alloc::format!("{}", Json::bool(true)), "true");
1073 assert_eq!(alloc::format!("{}", Json::bool(false)), "false");
1074 assert_eq!(alloc::format!("{}", Json::number(3.0)), "3");
1076 assert_eq!(alloc::format!("{}", Json::integer(-42)), "-42");
1077 assert_eq!(alloc::format!("{}", Json::number(1.5)), "1.5");
1078 assert_eq!(alloc::format!("{}", Json::string("x")), "\"x\"");
1079 }
1080
1081 #[test]
1082 fn display_of_non_finite_numbers_is_not_json() {
1083 assert_eq!(alloc::format!("{}", Json::number(f64::NAN)), "NaN");
1085 assert_eq!(alloc::format!("{}", Json::number(f64::INFINITY)), "inf");
1086 assert_eq!(alloc::format!("{}", Json::number(f64::NEG_INFINITY)), "-inf");
1087 assert_eq!(alloc::format!("{}", Json::number(-0.0)), "0");
1089 }
1090
1091 #[test]
1092 fn display_does_not_escape_strings() {
1093 let j = Json::string("a\"b\nc");
1096 assert_eq!(alloc::format!("{j}"), "\"a\"b\nc\"");
1097 }
1098
1099 #[test]
1100 fn display_of_container_emits_the_raw_payload_even_when_corrupt() {
1101 assert_eq!(
1102 alloc::format!("{}", raw(JsonType::Array, "[1, 2]")),
1103 "[1, 2]"
1104 );
1105 assert_eq!(
1106 alloc::format!("{}", raw(JsonType::Object, "<<garbage>>")),
1107 "<<garbage>>"
1108 );
1109 assert_eq!(alloc::format!("{}", raw(JsonType::Array, "")), "");
1110 }
1111
1112 #[test]
1117 fn parse_error_display_with_and_without_position() {
1118 let with_pos = JsonParseError {
1119 message: az("expected value"),
1120 line: 3,
1121 column: 7,
1122 };
1123 assert_eq!(alloc::format!("{with_pos}"), "3:7: expected value");
1124
1125 let no_pos = JsonParseError {
1126 message: az("expected value"),
1127 line: 0,
1128 column: 99,
1129 };
1130 assert_eq!(alloc::format!("{no_pos}"), "expected value");
1131 }
1132
1133 #[test]
1134 fn parse_error_display_edge_values_do_not_panic() {
1135 let empty = JsonParseError {
1136 message: az(""),
1137 line: 0,
1138 column: 0,
1139 };
1140 assert_eq!(alloc::format!("{empty}"), "");
1141
1142 let maxed = JsonParseError {
1143 message: az("π"),
1144 line: u32::MAX,
1145 column: u32::MAX,
1146 };
1147 assert_eq!(
1148 alloc::format!("{maxed}"),
1149 alloc::format!("{}:{}: π", u32::MAX, u32::MAX)
1150 );
1151 }
1152
1153 #[test]
1158 fn key_value_create_preserves_key_and_value() {
1159 let kv = JsonKeyValue::create(az(""), Json::null());
1160 assert_eq!(kv.key.as_str(), "");
1161 assert!(kv.value.is_null());
1162
1163 let big_key = "k".repeat(100_000);
1164 let kv = JsonKeyValue::create(
1165 AzString::from(big_key.clone()),
1166 Json::number(f64::NEG_INFINITY),
1167 );
1168 assert_eq!(kv.key.as_str().len(), big_key.len());
1169 assert!(kv.value.is_number());
1170
1171 let kv = JsonKeyValue::create(az("π/\u{0}"), Json::string("v"));
1172 assert_eq!(kv.key.as_str(), "π/\u{0}");
1173 assert_eq!(kv.value.as_string(), OptionString::Some(az("v")));
1174 }
1175
1176 #[test]
1181 fn json_vec_copy_from_array_null_ptr_is_empty_even_at_usize_max_len() {
1182 let v = JsonVec::copy_from_array(core::ptr::null(), 0);
1185 assert!(v.is_empty());
1186 let v = JsonVec::copy_from_array(core::ptr::null(), usize::MAX);
1187 assert!(v.is_empty());
1188 assert_eq!(v.len(), 0);
1189 }
1190
1191 #[test]
1192 fn json_vec_copy_from_array_zero_len_with_valid_ptr_is_empty() {
1193 let items = [Json::null(), Json::bool(true)];
1194 let v = JsonVec::copy_from_array(items.as_ptr(), 0);
1195 assert!(v.is_empty());
1196 }
1197
1198 #[test]
1199 fn json_vec_copy_from_array_deep_copies_the_elements() {
1200 let items = vec![
1201 Json::null(),
1202 Json::bool(true),
1203 Json::number(f64::NAN),
1204 Json::string("π"),
1205 ];
1206 let v = JsonVec::copy_from_array(items.as_ptr(), items.len());
1207 assert_eq!(v.len(), 4);
1208 assert_eq!(v.as_slice()[3].as_string(), OptionString::Some(az("π")));
1209 drop(items);
1211 assert!(v.as_slice()[0].is_null());
1212 assert_eq!(v.as_slice()[1].as_bool(), OptionBool::Some(true));
1213 assert_eq!(v.as_slice()[3].raw_string(), "π");
1214 }
1215
1216 #[test]
1217 fn key_value_vec_copy_from_array_null_ptr_is_empty_even_at_usize_max_len() {
1218 let v = JsonKeyValueVec::copy_from_array(core::ptr::null(), 0);
1219 assert!(v.is_empty());
1220 let v = JsonKeyValueVec::copy_from_array(core::ptr::null(), usize::MAX);
1221 assert!(v.is_empty());
1222 assert_eq!(v.len(), 0);
1223 }
1224
1225 #[test]
1226 fn key_value_vec_copy_from_array_deep_copies_the_elements() {
1227 let items = vec![
1228 JsonKeyValue::create(az("a"), Json::integer(1)),
1229 JsonKeyValue::create(az(""), Json::null()),
1230 ];
1231 let v = JsonKeyValueVec::copy_from_array(items.as_ptr(), items.len());
1232 assert_eq!(v.len(), 2);
1233 let zero_len = JsonKeyValueVec::copy_from_array(items.as_ptr(), 0);
1234 assert!(zero_len.is_empty());
1235 drop(items);
1236 assert_eq!(v.as_slice()[0].key.as_str(), "a");
1237 assert_eq!(v.as_slice()[0].value.as_i64(), OptionI64::Some(1));
1238 assert_eq!(v.as_slice()[1].key.as_str(), "");
1239 }
1240
1241 #[test]
1246 #[cfg(feature = "serde-json")]
1247 fn parse_empty_and_whitespace_only_input_is_an_error() {
1248 for s in ["", " ", " ", "\t\n\r", "\u{feff}"] {
1249 let err = Json::parse(s).expect_err("empty/blank input must not parse");
1250 assert!(!err.message.as_str().is_empty());
1251 assert!(Json::parse_bytes(s.as_bytes()).is_err());
1252 }
1253 assert!(Json::parse_bytes(b"").is_err());
1254 }
1255
1256 #[test]
1257 #[cfg(feature = "serde-json")]
1258 fn parse_garbage_returns_err_and_never_panics() {
1259 for s in [
1260 "{", "}", "[", "]", ",", ":", "nul", "tru", "'a'", "{,}", "[,]", "{\"a\"}", "{\"a\":}",
1261 "[1,]", "{\"a\":1,}", "\"unterminated", "\\", "\u{0}", "01", "+1", ".5", "1.", "-",
1262 "0x10", "--1", "1e", "{'a':1}", "undefined",
1263 ] {
1264 assert!(Json::parse(s).is_err(), "{s:?} must be rejected");
1265 assert!(Json::parse_bytes(s.as_bytes()).is_err(), "{s:?} (bytes)");
1266 }
1267 }
1268
1269 #[test]
1270 #[cfg(feature = "serde-json")]
1271 fn parse_leading_and_trailing_junk() {
1272 assert_eq!(Json::parse(" 1 ").expect("padded"), Json::integer(1));
1274 assert_eq!(Json::parse("\n\t{}\r\n").expect("padded"), Json::parse("{}").expect("{}"));
1275 for s in ["1;garbage", "{} {}", "null null", "1 2", "[1] x"] {
1277 assert!(Json::parse(s).is_err(), "{s:?} must be rejected");
1278 }
1279 }
1280
1281 #[test]
1282 #[cfg(feature = "serde-json")]
1283 fn parse_bytes_rejects_invalid_utf8_without_panicking() {
1284 assert!(Json::parse_bytes(&[0xFF, 0xFE, 0x00]).is_err());
1285 assert!(Json::parse_bytes(&[b'"', 0xFF, b'"']).is_err());
1287 assert!(Json::parse_bytes(&[b'[', 0x80, b']']).is_err());
1289 }
1290
1291 #[test]
1292 #[cfg(feature = "serde-json")]
1293 fn parse_deeply_nested_input_errors_instead_of_overflowing_the_stack() {
1294 let deep = alloc::format!("{}{}", "[".repeat(10_000), "]".repeat(10_000));
1296 assert!(Json::parse(&deep).is_err());
1297 assert!(Json::parse_bytes(deep.as_bytes()).is_err());
1298
1299 let deep_obj = alloc::format!("{}1{}", "{\"a\":".repeat(10_000), "}".repeat(10_000));
1300 assert!(Json::parse(&deep_obj).is_err());
1301
1302 let unbalanced = "[".repeat(100_000);
1304 assert!(Json::parse(&unbalanced).is_err());
1305 }
1306
1307 #[test]
1308 #[cfg(feature = "serde-json")]
1309 fn parse_extremely_long_input_terminates() {
1310 const N: usize = 200_000;
1311 let mut doc = String::with_capacity(N * 2 + 2);
1312 doc.push('[');
1313 for i in 0..N {
1314 if i > 0 {
1315 doc.push(',');
1316 }
1317 doc.push('1');
1318 }
1319 doc.push(']');
1320 let j = Json::parse(&doc).expect("a long flat array must parse");
1321 assert!(j.is_array());
1322 assert_eq!(j.len(), N);
1323
1324 let payload = "a".repeat(1_000_000);
1326 let j = Json::parse(&alloc::format!("\"{payload}\"")).expect("long string");
1327 assert_eq!(j.as_string(), OptionString::Some(AzString::from(payload)));
1328 }
1329
1330 #[test]
1331 #[cfg(feature = "serde-json")]
1332 fn parse_unicode_input() {
1333 let j = Json::parse("\"\u{1F600}\"").expect("emoji");
1334 assert_eq!(j.as_string(), OptionString::Some(az("\u{1F600}")));
1335
1336 let j = Json::parse("\"e\\u0301\\u202e\\u0000\"").expect("escapes");
1338 assert_eq!(
1339 j.as_string(),
1340 OptionString::Some(az("e\u{0301}\u{202e}\u{0}"))
1341 );
1342
1343 let j = Json::parse("{\"ΠΊΠ»ΡΡ\":\"Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅\"}").expect("cyrillic keys");
1345 assert_eq!(
1346 j.get_key("ΠΊΠ»ΡΡ").expect("key").as_string(),
1347 OptionString::Some(az("Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅"))
1348 );
1349
1350 assert!(Json::parse("\"\\ud800\"").is_err());
1352 }
1353
1354 #[test]
1355 #[cfg(feature = "serde-json")]
1356 fn parse_boundary_numbers() {
1357 assert_eq!(Json::parse("0").expect("0").as_i64(), OptionI64::Some(0));
1358 match Json::parse("-0").expect("-0").as_number() {
1360 OptionF64::Some(v) => assert_eq!(v, 0.0),
1361 OptionF64::None => panic!("-0 must be a number"),
1362 }
1363
1364 assert_eq!(
1366 Json::parse("-9223372036854775808").expect("i64::MIN").as_i64(),
1367 OptionI64::Some(i64::MIN)
1368 );
1369 let max = Json::parse("9223372036854775807").expect("i64::MAX");
1372 assert_eq!(max.as_number(), OptionF64::Some(two_pow_63()));
1373 assert_eq!(max.as_i64(), OptionI64::None);
1374 assert_eq!(
1376 Json::parse("18446744073709551615").expect("u64::MAX").as_i64(),
1377 OptionI64::None
1378 );
1379
1380 assert!(Json::parse("1e308").expect("1e308").is_number());
1381 assert!(Json::parse("1e-308").expect("1e-308").is_number());
1382
1383 for s in ["NaN", "nan", "Infinity", "-Infinity", "inf"] {
1385 assert!(Json::parse(s).is_err(), "{s:?} is not valid JSON");
1386 }
1387
1388 if let Ok(j) = Json::parse("1e400") {
1391 assert!(j.is_number());
1392 }
1393 if let Ok(j) = Json::parse("1e-400") {
1394 assert!(j.is_number());
1395 }
1396 }
1397
1398 #[test]
1399 #[cfg(feature = "serde-json")]
1400 fn parse_valid_minimal_inputs() {
1401 assert_eq!(Json::parse("null").expect("null"), Json::null());
1402 assert_eq!(Json::parse("true").expect("true"), Json::bool(true));
1403 assert_eq!(Json::parse("false").expect("false"), Json::bool(false));
1404 assert_eq!(Json::parse("1").expect("1"), Json::integer(1));
1405 assert_eq!(Json::parse("1.5").expect("1.5"), Json::number(1.5));
1406 assert_eq!(Json::parse("\"s\"").expect("str"), Json::string("s"));
1407 assert!(Json::parse("[]").expect("[]").is_array());
1408 assert!(Json::parse("{}").expect("{}").is_object());
1409 assert_eq!(
1411 Json::parse_bytes(b"{\"a\":[1,2]}").expect("bytes"),
1412 Json::parse("{\"a\":[1,2]}").expect("str")
1413 );
1414 }
1415
1416 #[cfg(feature = "serde-json")]
1421 fn round_trip_corpus() -> Vec<Json> {
1422 vec![
1423 Json::null(),
1424 Json::bool(true),
1425 Json::bool(false),
1426 Json::integer(0),
1427 Json::integer(-1),
1428 Json::integer(i64::MIN),
1429 Json::number(1.5),
1430 Json::number(-0.25),
1431 Json::number(1e21),
1432 Json::string(""),
1433 Json::string("π \"quoted\" \\slash\\ \n\t \u{0}"),
1434 Json::parse("[]").expect("[]"),
1435 Json::parse("{}").expect("{}"),
1436 Json::parse("[1,[2,[3]],{\"k\":null}]").expect("nested array"),
1437 Json::parse("{\"a\":{\"b\":[1,2,3]},\"ΓΌnΓ―\":\"π\"}").expect("nested object"),
1438 ]
1439 }
1440
1441 #[test]
1442 #[cfg(feature = "serde-json")]
1443 fn parse_of_to_json_string_reproduces_the_value() {
1444 for j in round_trip_corpus() {
1445 let encoded = j.to_json_string();
1446 let decoded = Json::parse(encoded.as_str())
1447 .unwrap_or_else(|e| panic!("{encoded:?} must re-parse: {e}"));
1448 assert_eq!(decoded, j, "round trip failed for {encoded:?}");
1449 }
1450 }
1451
1452 #[test]
1453 #[cfg(feature = "serde-json")]
1454 fn serialize_parse_serialize_is_idempotent() {
1455 for j in round_trip_corpus() {
1456 let once = j.to_json_string();
1457 let twice = Json::parse(once.as_str()).expect("re-parse").to_json_string();
1458 assert_eq!(once.as_str(), twice.as_str());
1459 }
1460 }
1461
1462 #[test]
1463 #[cfg(feature = "serde-json")]
1464 fn round_trip_extreme_floats() {
1465 for n in [f64::MAX, f64::MIN, f64::MIN_POSITIVE, -f64::MIN_POSITIVE] {
1466 let j = Json::number(n);
1467 let encoded = j.to_json_string();
1468 let decoded = Json::parse(encoded.as_str())
1469 .unwrap_or_else(|e| panic!("{encoded:?} must re-parse: {e}"));
1470 assert_eq!(decoded.as_number(), OptionF64::Some(n));
1471 }
1472 }
1473
1474 #[test]
1475 #[cfg(feature = "serde-json")]
1476 fn non_finite_numbers_do_not_survive_to_json_string() {
1477 for (n, token) in [
1484 (f64::NAN, "NaN"),
1485 (f64::INFINITY, "inf"),
1486 (f64::NEG_INFINITY, "-inf"),
1487 ] {
1488 let j = Json::number(n);
1489 let encoded = j.to_json_string();
1490 assert_eq!(encoded.as_str(), token);
1491 assert!(
1492 Json::parse(encoded.as_str()).is_err(),
1493 "{token} is not valid JSON"
1494 );
1495 assert_eq!(j.to_serde_value(), serde_json::Value::Null);
1497 }
1498 }
1499
1500 #[test]
1505 #[cfg(feature = "serde-json")]
1506 fn from_serde_value_maps_every_variant() {
1507 use serde_json::json;
1508
1509 assert!(Json::from_serde_value(json!(null)).is_null());
1510 assert_eq!(
1511 Json::from_serde_value(json!(true)).as_bool(),
1512 OptionBool::Some(true)
1513 );
1514 assert_eq!(
1515 Json::from_serde_value(json!(-3)).as_i64(),
1516 OptionI64::Some(-3)
1517 );
1518 assert_eq!(
1519 Json::from_serde_value(json!("π")).as_string(),
1520 OptionString::Some(az("π"))
1521 );
1522
1523 let arr = Json::from_serde_value(json!([1, "two", null]));
1524 assert!(arr.is_array());
1525 assert_eq!(arr.len(), 3);
1526 assert_eq!(arr.get_index(1).expect("idx 1"), Json::string("two"));
1527
1528 let obj = Json::from_serde_value(json!({"a": 1, "b": {"c": []}}));
1529 assert!(obj.is_object());
1530 assert_eq!(obj.len(), 2);
1531 assert_eq!(obj.get_key("a").expect("a"), Json::integer(1));
1532 assert!(Json::parse(obj.raw_string()).is_ok());
1534 }
1535
1536 #[test]
1537 #[cfg(feature = "serde-json")]
1538 fn to_serde_value_round_trips_through_from_serde_value() {
1539 use serde_json::json;
1540
1541 for v in [
1542 json!(null),
1543 json!(false),
1544 json!(0),
1545 json!(-1.5),
1546 json!(""),
1547 json!([]),
1548 json!({}),
1549 json!({"k": [1, {"n": null}], "ΓΌ": "π"}),
1550 ] {
1551 let back = Json::from_serde_value(v.clone()).to_serde_value();
1552 assert_eq!(back, v);
1553 }
1554 }
1555
1556 #[test]
1557 #[cfg(feature = "serde-json")]
1558 fn to_serde_value_on_a_corrupt_container_yields_null() {
1559 assert_eq!(
1560 raw(JsonType::Array, "not json").to_serde_value(),
1561 serde_json::Value::Null
1562 );
1563 assert_eq!(
1564 raw(JsonType::Object, "").to_serde_value(),
1565 serde_json::Value::Null
1566 );
1567 }
1568
1569 #[test]
1574 #[cfg(feature = "serde-json")]
1575 fn array_constructor_handles_empty_and_non_finite_members() {
1576 let empty = Json::array(JsonVec::new());
1577 assert!(empty.is_array());
1578 assert_eq!(empty.len(), 0);
1579 assert!(empty.is_empty());
1580 assert_eq!(empty.raw_string(), "[]");
1581
1582 let with_nan = Json::array(JsonVec::from_vec(vec![
1585 Json::number(f64::NAN),
1586 Json::number(f64::INFINITY),
1587 Json::integer(1),
1588 ]));
1589 assert_eq!(with_nan.raw_string(), "[null,null,1]");
1590 assert_eq!(with_nan.len(), 3);
1591 assert!(Json::parse(with_nan.raw_string()).is_ok());
1592 }
1593
1594 #[test]
1595 #[cfg(feature = "serde-json")]
1596 fn object_constructor_dedupes_duplicate_keys_last_one_wins() {
1597 let empty = Json::object(JsonKeyValueVec::new());
1598 assert!(empty.is_object());
1599 assert!(empty.is_empty());
1600 assert_eq!(empty.raw_string(), "{}");
1601
1602 let dup = Json::object(JsonKeyValueVec::from_vec(vec![
1603 JsonKeyValue::create(az("k"), Json::integer(1)),
1604 JsonKeyValue::create(az("k"), Json::integer(2)),
1605 JsonKeyValue::create(az(""), Json::null()),
1606 ]));
1607 assert_eq!(dup.len(), 2, "duplicate keys collapse into one entry");
1608 assert_eq!(dup.get_key("k").expect("k"), Json::integer(2));
1609 assert!(dup.get_key("").expect("empty key").is_null());
1610 }
1611
1612 #[test]
1613 #[cfg(feature = "serde-json")]
1614 fn object_constructor_escapes_hostile_keys() {
1615 let obj = Json::object(JsonKeyValueVec::from_vec(vec![JsonKeyValue::create(
1616 az("\"}\nπ"),
1617 Json::string("v"),
1618 )]));
1619 let reparsed = Json::parse(obj.raw_string()).expect("hostile key must be escaped");
1621 assert_eq!(
1622 reparsed.get_key("\"}\nπ").expect("key").as_string(),
1623 OptionString::Some(az("v"))
1624 );
1625 }
1626
1627 #[test]
1632 #[cfg(feature = "serde-json")]
1633 fn len_is_zero_for_scalars_which_makes_is_empty_true() {
1634 for j in [
1637 Json::null(),
1638 Json::bool(true),
1639 Json::integer(7),
1640 Json::string("hello"),
1641 ] {
1642 assert_eq!(j.len(), 0);
1643 assert!(j.is_empty());
1644 }
1645 }
1646
1647 #[test]
1648 #[cfg(feature = "serde-json")]
1649 fn len_of_containers_and_corrupt_payloads() {
1650 assert_eq!(Json::parse("[1,2,3]").expect("arr").len(), 3);
1651 assert_eq!(Json::parse("{\"a\":1}").expect("obj").len(), 1);
1652 assert_eq!(Json::parse("[]").expect("[]").len(), 0);
1653 assert_eq!(raw(JsonType::Array, "not json").len(), 0);
1655 assert!(raw(JsonType::Object, "").is_empty());
1656 assert_eq!(raw(JsonType::Array, "{\"a\":1}").len(), 0);
1658 }
1659
1660 #[test]
1665 #[cfg(feature = "serde-json")]
1666 fn get_index_boundaries() {
1667 let arr = Json::parse("[10,20]").expect("arr");
1668 assert_eq!(arr.get_index(0).expect("0"), Json::integer(10));
1669 assert_eq!(arr.get_index(1).expect("1"), Json::integer(20));
1670 assert!(arr.get_index(2).is_none());
1671 assert!(arr.get_index(usize::MAX).is_none());
1672
1673 assert!(Json::parse("[]").expect("[]").get_index(0).is_none());
1674 assert!(Json::parse("{\"0\":1}").expect("obj").get_index(0).is_none());
1676 assert!(Json::string("abc").get_index(0).is_none());
1677 assert!(raw(JsonType::Array, "not json").get_index(0).is_none());
1678 assert!(raw(JsonType::Array, "{\"a\":1}").get_index(0).is_none());
1679 }
1680
1681 #[test]
1682 #[cfg(feature = "serde-json")]
1683 fn get_key_edge_inputs() {
1684 let obj = Json::parse("{\"\":1,\"a\":null,\"π\":[]}").expect("obj");
1685 assert_eq!(obj.get_key("").expect("empty key"), Json::integer(1));
1686 assert!(obj.get_key("a").expect("a").is_null());
1687 assert!(obj.get_key("π").expect("emoji").is_array());
1688 assert!(obj.get_key("missing").is_none());
1689 assert!(obj.get_key(" a").is_none());
1691 assert!(obj.get_key("A").is_none());
1692 assert!(obj.get_key(&"k".repeat(1_000_000)).is_none());
1694 assert!(Json::parse("[1]").expect("arr").get_key("0").is_none());
1696 assert!(Json::null().get_key("").is_none());
1697 assert!(raw(JsonType::Object, "not json").get_key("a").is_none());
1698 }
1699
1700 #[test]
1701 #[cfg(feature = "serde-json")]
1702 fn keys_returns_every_key_and_nothing_for_non_objects() {
1703 let obj = Json::parse("{\"b\":1,\"a\":2,\"\":3}").expect("obj");
1704 let keys = obj.keys();
1705 assert_eq!(keys.len(), 3);
1706 for expected in ["a", "b", ""] {
1707 assert!(
1708 keys.iter().any(|k| k.as_str() == expected),
1709 "missing key {expected:?}"
1710 );
1711 }
1712 assert!(Json::parse("{}").expect("{}").keys().is_empty());
1713 assert!(Json::parse("[1,2]").expect("arr").keys().is_empty());
1714 assert!(Json::string("x").keys().is_empty());
1715 assert!(raw(JsonType::Object, "not json").keys().is_empty());
1716 }
1717
1718 #[test]
1719 #[cfg(feature = "serde-json")]
1720 fn to_array_and_to_object_on_wrong_types_and_corrupt_payloads() {
1721 let arr = Json::parse("[null,1]").expect("arr").to_array().expect("to_array");
1722 assert_eq!(arr.len(), 2);
1723 assert!(arr.as_slice()[0].is_null());
1724 assert_eq!(arr.as_slice()[1].as_i64(), OptionI64::Some(1));
1725
1726 let obj = Json::parse("{\"a\":\"v\"}").expect("obj").to_object().expect("to_object");
1727 assert_eq!(obj.len(), 1);
1728 assert_eq!(obj.as_slice()[0].key.as_str(), "a");
1729 assert_eq!(
1730 obj.as_slice()[0].value.as_string(),
1731 OptionString::Some(az("v"))
1732 );
1733
1734 assert!(Json::parse("[]").expect("[]").to_array().expect("empty").is_empty());
1735 assert!(Json::parse("{}").expect("{}").to_object().expect("empty").is_empty());
1736
1737 assert!(Json::null().to_array().is_none());
1739 assert!(Json::string("[]").to_array().is_none());
1740 assert!(Json::parse("[]").expect("[]").to_object().is_none());
1741 assert!(raw(JsonType::Array, "not json").to_array().is_none());
1742 assert!(raw(JsonType::Object, "").to_object().is_none());
1743 assert!(raw(JsonType::Array, "{\"a\":1}").to_array().is_none());
1744 assert!(raw(JsonType::Object, "[1]").to_object().is_none());
1745 }
1746
1747 #[test]
1752 #[cfg(feature = "serde-json")]
1753 fn to_json_string_escapes_strings_unlike_display() {
1754 let j = Json::string("a\"b\nc\\d\u{0}");
1755 let encoded = j.to_json_string();
1756 assert_eq!(Json::parse(encoded.as_str()).expect("escaped"), j);
1758 assert_ne!(encoded.as_str(), alloc::format!("{j}"));
1760 }
1761
1762 #[test]
1763 #[cfg(feature = "serde-json")]
1764 fn to_string_pretty_matches_to_json_string_for_scalars() {
1765 for j in [
1766 Json::null(),
1767 Json::bool(false),
1768 Json::integer(-7),
1769 Json::number(0.5),
1770 Json::string("π"),
1771 ] {
1772 assert_eq!(j.to_string_pretty().as_str(), j.to_json_string().as_str());
1773 }
1774 }
1775
1776 #[test]
1777 #[cfg(feature = "serde-json")]
1778 fn to_string_pretty_of_containers_reparses_to_the_same_value() {
1779 let j = Json::parse("{\"a\":[1,{\"b\":null}],\"c\":{}}").expect("obj");
1780 let pretty = j.to_string_pretty();
1781 assert!(pretty.as_str().contains('\n'), "pretty output must be indented");
1782 assert_eq!(Json::parse(pretty.as_str()).expect("pretty reparses"), j);
1783
1784 let corrupt = raw(JsonType::Object, "not json");
1786 assert_eq!(corrupt.to_string_pretty().as_str(), "not json");
1787 assert_eq!(raw(JsonType::Array, "").to_string_pretty().as_str(), "");
1788 }
1789
1790 #[test]
1795 #[cfg(feature = "serde-json")]
1796 fn jq_on_scalars_only_matches_the_empty_pointer() {
1797 for j in [
1798 Json::null(),
1799 Json::bool(true),
1800 Json::integer(1),
1801 Json::string("s"),
1802 ] {
1803 assert_eq!(j.jq(""), j);
1804 assert!(j.jq("/").is_null());
1805 assert!(j.jq("/a").is_null());
1806 assert!(j.jq("nonsense").is_null());
1807 assert_eq!(j.jq_all("").as_ref().len(), 1);
1808 assert_eq!(j.jq_all("/a").as_ref().len(), 0);
1809 }
1810 }
1811
1812 #[test]
1813 #[cfg(feature = "serde-json")]
1814 fn jq_navigates_and_degrades_to_null() {
1815 let j = Json::parse("{\"a\":{\"b\":[10,20]},\"\":1}").expect("doc");
1816 assert_eq!(j.jq(""), j, "the empty pointer selects the whole document");
1817 assert_eq!(j.jq("/a/b/1"), Json::integer(20));
1818 assert_eq!(j.jq("/"), Json::integer(1), "'/' selects the empty-string key");
1819
1820 assert!(j.jq("/a/b/2").is_null(), "out-of-range index");
1822 assert!(j.jq("/a/b/-1").is_null(), "negative index is not a usize");
1823 assert!(j.jq("/a/b/99999999999999999999").is_null(), "index overflows usize");
1824 assert!(j.jq("a/b").is_null(), "pointer must start with '/'");
1825 assert!(j.jq("/missing").is_null());
1826 assert!(j.jq(&"/a".repeat(100_000)).is_null(), "huge pointer");
1827 assert!(j.jq("/a/b/1/deeper").is_null(), "descending through a scalar");
1828 assert!(raw(JsonType::Object, "not json").jq("/a").is_null());
1829 }
1830
1831 #[test]
1832 #[cfg(feature = "serde-json")]
1833 fn jq_all_wildcards_and_empty_results() {
1834 let j = Json::parse("{\"a\":[{\"v\":1},{\"v\":2}],\"b\":{\"v\":3},\"c\":7}").expect("doc");
1835
1836 assert_eq!(j.jq_all("/a/*/v").as_ref().len(), 2);
1837 assert_eq!(j.jq_all("/*/v").as_ref().len(), 1);
1839 assert_eq!(j.jq_all("/*").as_ref().len(), 3);
1840 assert_eq!(j.jq_all("").as_ref().len(), 1);
1841
1842 assert_eq!(j.jq_all("/missing/*").as_ref().len(), 0);
1844 assert_eq!(j.jq_all("a").as_ref().len(), 0);
1845 assert_eq!(j.jq_all("/c/*").as_ref().len(), 0, "wildcard over a scalar");
1846 assert_eq!(j.jq_all("/*/*/*/*/*").as_ref().len(), 0);
1847 assert_eq!(
1848 raw(JsonType::Array, "not json").jq_all("/*").as_ref().len(),
1849 0
1850 );
1851
1852 let many = "/*".repeat(10_000);
1854 assert_eq!(j.jq_all(&many).as_ref().len(), 0);
1855 }
1856
1857 #[test]
1862 #[cfg(feature = "serde-json")]
1863 fn jq_all_recursive_depth_honours_the_wildcard_cap() {
1864 let value = serde_json::json!({"a": 1});
1865
1866 assert_eq!(Json::jq_all_recursive_depth(&value, "/a", 0).len(), 1);
1868 assert_eq!(
1870 Json::jq_all_recursive_depth(&value, "/a", Json::JQ_MAX_WILDCARD_DEPTH).len(),
1871 1
1872 );
1873 assert_eq!(
1875 Json::jq_all_recursive_depth(&value, "/a", Json::JQ_MAX_WILDCARD_DEPTH + 1).len(),
1876 0
1877 );
1878 assert_eq!(Json::jq_all_recursive_depth(&value, "/*", usize::MAX).len(), 0);
1881 assert_eq!(Json::jq_all_recursive_depth(&value, "", usize::MAX).len(), 0);
1882 }
1883
1884 #[test]
1885 #[cfg(feature = "serde-json")]
1886 fn jq_all_wildcard_fanout_deeper_than_the_cap_returns_empty() {
1887 fn nest(depth: usize) -> serde_json::Value {
1891 let mut v = serde_json::Value::from(1_i64);
1892 for _ in 0..depth {
1893 v = serde_json::Value::Array(vec![v]);
1894 }
1895 v
1896 }
1897
1898 let shallow = nest(400);
1900 let found = Json::jq_all_recursive(&shallow, &"/*".repeat(400));
1901 assert_eq!(found.len(), 1);
1902 assert_eq!(found[0].as_i64(), OptionI64::Some(1));
1903
1904 let deep = nest(600);
1906 assert!(Json::jq_all_recursive(&deep, &"/*".repeat(600)).is_empty());
1907 }
1908}