1#![cfg_attr(not(feature = "std"), no_std)]
52#![forbid(unsafe_code)]
53#![warn(missing_docs)]
54
55extern crate alloc;
56
57#[cfg(feature = "canonical")]
58mod canonical;
59mod error;
60#[cfg(feature = "validate")]
61mod form;
62mod limits;
63mod number;
64mod parse;
65#[cfg(feature = "primitives")]
66mod primitives;
67mod value;
68mod write;
69
70#[cfg(feature = "canonical")]
71pub use canonical::{to_canonical_string, to_canonical_vec};
72pub use error::{
73 JsonError, JsonErrorKind, JsonLimitKind, JsonNumberError, JsonPath, JsonPathSegment,
74};
75#[cfg(feature = "validate")]
76pub use form::JsonForm;
77pub use limits::JsonLimits;
78pub use number::JsonNumber;
79pub use parse::{parse, parse_str, parse_with_limits};
80#[cfg(feature = "primitives")]
81pub use primitives::{JsonExtractError, JsonExtractErrorKind};
82pub use value::{JsonMember, JsonObject, JsonValue};
83pub use write::{to_compact_string, to_compact_vec};
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88 use alloc::string::{String, ToString};
89
90 fn parse_ok(input: &str) -> JsonValue {
91 parse_str(input).expect("should parse")
92 }
93
94 fn kind(input: &str) -> JsonErrorKind {
95 parse_str(input).expect_err("should fail").kind().clone()
96 }
97
98 #[test]
101 fn parses_scalars() {
102 assert_eq!(parse_ok("null"), JsonValue::Null);
103 assert_eq!(parse_ok("true"), JsonValue::Bool(true));
104 assert_eq!(parse_ok("false"), JsonValue::Bool(false));
105 assert_eq!(parse_ok("\"hi\"").as_str(), Some("hi"));
106 assert_eq!(parse_ok("42").as_number().unwrap().to_i64().unwrap(), 42);
107 }
108
109 #[test]
110 fn whitespace_is_allowed_around_values() {
111 assert_eq!(parse_ok(" \t\r\n 7 \n").as_number().unwrap().as_str(), "7");
112 }
113
114 #[test]
115 fn only_json_whitespace_is_accepted() {
116 assert_eq!(kind("\u{0B}1"), JsonErrorKind::UnexpectedByte);
118 }
119
120 #[test]
123 fn parses_object_and_array() {
124 let value = parse_ok(r#"{"a":[1,2,3],"b":{"c":null}}"#);
125 let obj = value.as_object().unwrap();
126 assert_eq!(obj.len(), 2);
127 assert_eq!(obj.get("a").unwrap().as_array().unwrap().len(), 3);
128 assert!(obj
129 .get("b")
130 .unwrap()
131 .as_object()
132 .unwrap()
133 .get("c")
134 .unwrap()
135 .is_null());
136 }
137
138 #[test]
139 fn empty_containers() {
140 assert_eq!(parse_ok("[]").as_array().unwrap().len(), 0);
141 assert_eq!(parse_ok("{}").as_object().unwrap().len(), 0);
142 }
143
144 #[test]
147 fn rejects_trailing_data() {
148 assert_eq!(kind("1 2"), JsonErrorKind::TrailingData);
149 assert_eq!(kind("{} x"), JsonErrorKind::TrailingData);
150 }
151
152 #[test]
153 fn rejects_comments_and_trailing_commas() {
154 assert_eq!(kind("1 // c"), JsonErrorKind::TrailingData);
155 assert_eq!(kind("[1,]"), JsonErrorKind::UnexpectedByte);
156 assert_eq!(kind(r#"{"a":1,}"#), JsonErrorKind::UnexpectedByte);
157 }
158
159 #[test]
160 fn rejects_bad_numbers() {
161 for bad in ["01", "1.", "-", "1e", "1e+", "00", "1.2.3"] {
162 assert_eq!(kind(bad), JsonErrorKind::InvalidNumber, "input {bad:?}");
163 }
164 assert_eq!(kind(".5"), JsonErrorKind::UnexpectedByte);
167 assert_eq!(kind("+1"), JsonErrorKind::UnexpectedByte);
168 assert_eq!(kind("0x1"), JsonErrorKind::TrailingData);
169 }
170
171 #[test]
172 fn rejects_nan_and_infinity() {
173 assert_eq!(kind("NaN"), JsonErrorKind::UnexpectedByte);
174 assert_eq!(kind("Infinity"), JsonErrorKind::UnexpectedByte);
175 assert_eq!(kind("-Infinity"), JsonErrorKind::InvalidNumber);
176 }
177
178 #[test]
179 fn rejects_unescaped_control_and_bad_escapes() {
180 assert_eq!(kind("\"\u{01}\""), JsonErrorKind::UnescapedControlCharacter);
181 assert_eq!(kind(r#""\x""#), JsonErrorKind::InvalidEscape);
182 assert_eq!(kind(r#""\u00""#), JsonErrorKind::InvalidUnicodeEscape);
183 }
184
185 #[test]
186 fn rejects_lone_surrogates() {
187 assert_eq!(kind(r#""\uD800""#), JsonErrorKind::LoneSurrogate);
188 assert_eq!(kind(r#""\uDC00""#), JsonErrorKind::LoneSurrogate);
189 assert_eq!(kind(r#""\uD800a""#), JsonErrorKind::LoneSurrogate);
190 }
191
192 #[test]
193 fn accepts_valid_surrogate_pair() {
194 assert_eq!(parse_ok(r#""𝄞""#).as_str(), Some("\u{1D11E}"));
195 }
196
197 #[test]
198 fn rejects_invalid_utf8_and_bom() {
199 assert_eq!(
200 parse(&[0xff]).unwrap_err().kind().clone(),
201 JsonErrorKind::InvalidUtf8
202 );
203 assert_eq!(
204 parse(&[0xEF, 0xBB, 0xBF, b'1']).unwrap_err().kind().clone(),
205 JsonErrorKind::InvalidUtf8
206 );
207 }
208
209 #[test]
212 fn escape_and_literal_decode_equally() {
213 assert_eq!(parse_ok(r#""a""#), parse_ok(r#""a""#));
214 }
215
216 #[test]
217 fn decodes_named_escapes() {
218 assert_eq!(
219 parse_ok(r#""\n\t\r\b\f\"\\\/""#).as_str(),
220 Some("\n\t\r\u{08}\u{0C}\"\\/")
221 );
222 }
223
224 #[test]
227 fn rejects_duplicate_keys() {
228 assert_eq!(kind(r#"{"a":1,"a":2}"#), JsonErrorKind::DuplicateKey);
229 }
230
231 #[test]
232 fn duplicate_detection_is_after_escape_decoding() {
233 assert_eq!(
234 kind(r#"{"role":"user","role":"admin"}"#),
235 JsonErrorKind::DuplicateKey
236 );
237 }
238
239 #[test]
242 fn enforces_depth_limit() {
243 let limits = JsonLimits::new().with_max_depth(3);
244 assert!(parse_with_limits(b"[[[1]]]", limits).is_ok());
245 assert_eq!(
246 parse_with_limits(b"[[[[1]]]]", limits)
247 .unwrap_err()
248 .kind()
249 .clone(),
250 JsonErrorKind::LimitExceeded(JsonLimitKind::Depth)
251 );
252 }
253
254 #[test]
255 fn enforces_count_limits() {
256 let limits = JsonLimits::new();
257 let limits = JsonLimits {
258 max_array_items: 2,
259 max_object_members: 2,
260 max_total_nodes: 100,
261 ..limits
262 };
263 assert_eq!(
264 parse_with_limits(b"[1,2,3]", limits)
265 .unwrap_err()
266 .kind()
267 .clone(),
268 JsonErrorKind::LimitExceeded(JsonLimitKind::ArrayItems)
269 );
270 assert_eq!(
271 parse_with_limits(br#"{"a":1,"b":2,"c":3}"#, limits)
272 .unwrap_err()
273 .kind()
274 .clone(),
275 JsonErrorKind::LimitExceeded(JsonLimitKind::ObjectMembers)
276 );
277 }
278
279 #[test]
280 fn enforces_total_nodes_and_input_bytes() {
281 let nodes = JsonLimits::new().with_max_total_nodes(2);
282 assert_eq!(
283 parse_with_limits(b"[1,2]", nodes)
284 .unwrap_err()
285 .kind()
286 .clone(),
287 JsonErrorKind::LimitExceeded(JsonLimitKind::TotalNodes)
288 );
289 let bytes = JsonLimits::new().with_max_input_bytes(2);
290 assert_eq!(
291 parse_with_limits(b"[1]", bytes).unwrap_err().kind().clone(),
292 JsonErrorKind::LimitExceeded(JsonLimitKind::InputBytes)
293 );
294 }
295
296 #[test]
297 fn enforces_string_and_number_byte_limits() {
298 let s = JsonLimits {
299 max_string_bytes: 3,
300 ..JsonLimits::new()
301 };
302 assert_eq!(
303 parse_with_limits(br#""abcd""#, s)
304 .unwrap_err()
305 .kind()
306 .clone(),
307 JsonErrorKind::LimitExceeded(JsonLimitKind::StringBytes)
308 );
309 let n = JsonLimits {
310 max_number_bytes: 2,
311 ..JsonLimits::new()
312 };
313 assert_eq!(
314 parse_with_limits(b"12345", n).unwrap_err().kind().clone(),
315 JsonErrorKind::LimitExceeded(JsonLimitKind::NumberBytes)
316 );
317 }
318
319 #[test]
322 fn number_conversions() {
323 assert_eq!(parse_ok("-7").as_number().unwrap().to_i64().unwrap(), -7);
324 assert_eq!(parse_ok("7").as_number().unwrap().to_u64().unwrap(), 7);
325 assert!((parse_ok("1.5").as_number().unwrap().to_f64().unwrap() - 1.5).abs() < 1e-12);
326 assert_eq!(
327 parse_ok("1.5").as_number().unwrap().to_i64(),
328 Err(JsonNumberError::NotAnInteger)
329 );
330 assert_eq!(
331 parse_ok("99999999999999999999999")
332 .as_number()
333 .unwrap()
334 .to_i64(),
335 Err(JsonNumberError::OutOfRange)
336 );
337 assert_eq!(
338 parse_ok("1e400").as_number().unwrap().to_f64(),
339 Err(JsonNumberError::NotFinite)
340 );
341 }
342
343 #[test]
344 fn number_preserves_representation() {
345 assert_eq!(parse_ok("1.0").as_number().unwrap().as_str(), "1.0");
346 assert_ne!(parse_ok("1.0"), parse_ok("1")); }
348
349 #[test]
350 fn json_number_from_f64() {
351 assert_eq!(JsonNumber::try_from_f64(1.5).unwrap().as_str(), "1.5");
352 assert_eq!(
353 JsonNumber::try_from_f64(f64::NAN),
354 Err(JsonNumberError::NotFinite)
355 );
356 assert_eq!(
357 JsonNumber::try_from_f64(f64::INFINITY),
358 Err(JsonNumberError::NotFinite)
359 );
360 assert_eq!(JsonNumber::new("01"), Err(JsonNumberError::InvalidNumber));
361 }
362
363 #[test]
366 fn error_reports_location_and_path() {
367 let err = parse_str(" @").unwrap_err();
368 assert_eq!(err.kind().clone(), JsonErrorKind::UnexpectedByte);
369 assert_eq!(err.offset(), 2);
370 assert_eq!(err.line(), 1);
371 assert_eq!(err.column(), 3);
372
373 let err = parse_str(r#"{"users":[{"name":1},{"name":}]}"#).unwrap_err();
374 let path = err.path().unwrap().to_string();
375 assert_eq!(path, "$.users[1].name");
376 }
377
378 #[test]
381 fn compact_roundtrip_and_golden_bytes() {
382 let value = parse_ok(r#"{"a":1,"b":true,"c":[null,"x"]}"#);
383 assert_eq!(
384 to_compact_vec(&value),
385 br#"{"a":1,"b":true,"c":[null,"x"]}"#
386 );
387 let again = parse_str(&to_compact_string(&value)).unwrap();
389 assert_eq!(value, again);
390 }
391
392 #[test]
393 fn writer_escapes_control_and_special_characters() {
394 let mut object = JsonObject::new();
395 object.insert(
396 String::from("k"),
397 JsonValue::String(String::from("a\nb\"c\\\u{01}")),
398 );
399 let value = JsonValue::Object(object);
400 assert_eq!(to_compact_string(&value), r#"{"k":"a\nb\"c\\\u0001"}"#);
401 }
402
403 #[test]
404 fn object_insert_replaces_in_place() {
405 let mut object = JsonObject::new();
406 assert!(object
407 .insert(String::from("a"), JsonValue::Bool(true))
408 .is_none());
409 let old = object.insert(String::from("a"), JsonValue::Bool(false));
410 assert_eq!(old, Some(JsonValue::Bool(true)));
411 assert_eq!(object.len(), 1);
412 }
413
414 #[test]
415 fn deeply_nested_within_limits_does_not_overflow() {
416 let depth = 64;
418 let mut s = String::new();
419 for _ in 0..depth {
420 s.push('[');
421 }
422 s.push('1');
423 for _ in 0..depth {
424 s.push(']');
425 }
426 let _ = parse_str(&s); assert!(parse_with_limits(s.as_bytes(), JsonLimits::new().with_max_depth(64)).is_ok());
429 }
430
431 #[test]
432 fn arbitrary_bytes_never_panic() {
433 for input in [
435 &b""[..],
436 b" ",
437 b"{",
438 b"[",
439 b"\"",
440 b"\"\\",
441 b"\"\\u",
442 b"tru",
443 b"-",
444 b"[,]",
445 b"{,}",
446 b"\xff\xfe",
447 b"[[[",
448 b"}}}",
449 b"\"\\uD800\"",
450 b"1e",
451 b"{\"a\"}",
452 ] {
453 let _ = parse(input);
454 }
455 }
456
457 #[test]
458 fn json_test_suite_conformance() {
459 let must_accept: &[&[u8]] = &[
462 b"[]",
463 b"{}",
464 b"[1]",
465 b"[1,2,3]",
466 b"{\"a\":1}",
467 b"{\"a\":1,\"b\":2}",
468 b"[null,true,false]",
469 b"\"\\u0061\"",
470 b"\"\\uD834\\uDD1E\"", b"0",
472 b"-0",
473 b"123",
474 b"-123",
475 b"1.5",
476 b"1E10",
477 b"1e-10",
478 b"-1.2e+3",
479 b" 7 ",
480 b"\"abc\"",
481 b"true",
482 b"[[[[1]]]]",
483 b"{\"a\":{\"b\":[1,{\"c\":null}]}}",
484 ];
485 let must_reject: &[&[u8]] = &[
486 b"",
487 b"[1,]",
488 b"{\"a\":1,}",
489 b"[1 2]",
490 b"{\"a\" 1}",
491 b"{\"a\":1 \"b\":2}",
492 b"[1,,2]",
493 b"01",
494 b"1.",
495 b".1",
496 b"+1",
497 b"1e",
498 b"1e+",
499 b"0x1",
500 b"--1",
501 b"NaN",
502 b"Infinity",
503 b"[",
504 b"]",
505 b"{",
506 b"}",
507 b"\"",
508 b"\"\\x\"",
509 b"\"\\uZZZZ\"",
510 b"\"\x01\"", b"'single'",
512 b"1 1", b"tru",
514 b"nul",
515 b"\xEF\xBB\xBF1", b"\xff\xfe", b"\"\\uD800\"", b"/* comment */ 1",
519 b"{1:2}", ];
521 for input in must_accept {
522 assert!(parse(input).is_ok(), "should accept {input:?}");
523 }
524 for input in must_reject {
525 assert!(parse(input).is_err(), "should reject {input:?}");
526 }
527 }
528
529 #[test]
530 fn fuzz_parse_is_panic_free_and_roundtrips() {
531 let mut state: u64 = 0xD1B5_4A32_D192_ED03;
534 let mut next = || {
535 state ^= state << 13;
536 state ^= state >> 7;
537 state ^= state << 17;
538 state
539 };
540 let alphabet = b"{}[]\":,0123456789-+.eEtruefalsn \t\n\\/u";
542 let mut buf: Vec<u8> = Vec::new();
543 for _ in 0..40_000 {
544 buf.clear();
545 let len = (next() % 40) as usize;
546 for _ in 0..len {
547 let r = next();
548 let byte = if r & 7 == 0 {
549 (r >> 8) as u8 } else {
551 alphabet[((r >> 8) as usize) % alphabet.len()]
552 };
553 buf.push(byte);
554 }
555 if let Ok(value) = parse(&buf) {
556 let compact = to_compact_string(&value);
557 let reparsed = parse_str(&compact).expect("compact output must reparse");
558 assert_eq!(reparsed, value);
559 assert_eq!(to_compact_string(&reparsed), compact);
560
561 #[cfg(feature = "canonical")]
563 if let Ok(canonical) = to_canonical_string(&value) {
564 let again = parse_str(&canonical).expect("canonical output must reparse");
565 assert_eq!(to_canonical_string(&again).unwrap(), canonical);
566 }
567 }
568 }
569 }
570
571 #[test]
572 fn value_accessors_return_inner_or_none() {
573 let v = parse_ok(r#"{"b":true,"n":7,"s":"x","a":[1],"nil":null}"#);
574 let o = v.as_object().expect("object");
575 assert!(o.get("nil").unwrap().is_null());
576 assert_eq!(o.get("b").unwrap().as_bool(), Some(true));
577 assert_eq!(o.get("s").unwrap().as_str(), Some("x"));
578 assert_eq!(o.get("n").unwrap().as_number().unwrap().as_str(), "7");
579 assert_eq!(o.get("a").unwrap().as_array().unwrap().len(), 1);
580
581 let b = JsonValue::Bool(true);
583 assert!(!b.is_null());
584 assert_eq!(b.as_str(), None);
585 assert_eq!(b.as_number(), None);
586 assert_eq!(b.as_array(), None);
587 assert!(b.as_object().is_none());
588 assert_eq!(JsonValue::Null.as_bool(), None);
589 }
590
591 #[test]
592 fn object_insert_get_iter_and_len() {
593 let mut obj = JsonObject::new();
594 assert!(obj.is_empty());
595 assert_eq!(obj.len(), 0);
596 assert!(!obj.contains_key("k"));
597
598 assert_eq!(obj.insert("k".to_string(), JsonValue::Bool(false)), None);
599 assert!(obj.contains_key("k"));
600 assert_eq!(obj.len(), 1);
601
602 let old = obj.insert("k".to_string(), JsonValue::Bool(true));
604 assert_eq!(old, Some(JsonValue::Bool(false)));
605 assert_eq!(obj.len(), 1);
606 assert_eq!(obj.get("k"), Some(&JsonValue::Bool(true)));
607 assert_eq!(obj.get("missing"), None);
608
609 obj.insert("k2".to_string(), JsonValue::Null);
610 let members: Vec<&str> = obj.iter().map(|m| m.key()).collect();
611 assert_eq!(members, ["k", "k2"]);
612 assert_eq!(obj.iter().next().unwrap().value(), &JsonValue::Bool(true));
613
614 assert_eq!(JsonObject::default().len(), 0);
615 }
616
617 #[test]
618 fn number_conversions_cover_each_error() {
619 let int = JsonNumber::new("42").unwrap();
620 assert!(int.is_integer());
621 assert_eq!(int.to_i64(), Ok(42));
622 assert_eq!(int.to_u64(), Ok(42));
623 assert_eq!(int.to_f64(), Ok(42.0));
624
625 let neg = JsonNumber::new("-1").unwrap();
626 assert_eq!(neg.to_u64(), Err(JsonNumberError::OutOfRange));
627
628 let frac = JsonNumber::new("1.5").unwrap();
629 assert!(!frac.is_integer());
630 assert_eq!(frac.to_i64(), Err(JsonNumberError::NotAnInteger));
631 assert_eq!(frac.to_u64(), Err(JsonNumberError::NotAnInteger));
632 assert_eq!(frac.to_f64(), Ok(1.5));
633
634 let huge = JsonNumber::new("99999999999999999999").unwrap();
635 assert_eq!(huge.to_i64(), Err(JsonNumberError::OutOfRange));
636
637 let overflow = JsonNumber::new("1e400").unwrap();
638 assert_eq!(overflow.to_f64(), Err(JsonNumberError::NotFinite));
639
640 assert_eq!(JsonNumber::new("+1"), Err(JsonNumberError::InvalidNumber));
641 assert_eq!(JsonNumber::try_from_f64(2.5).unwrap().to_f64(), Ok(2.5));
642 assert_eq!(
643 JsonNumber::try_from_f64(f64::NAN),
644 Err(JsonNumberError::NotFinite)
645 );
646 assert_eq!(
647 JsonNumber::try_from_f64(f64::INFINITY),
648 Err(JsonNumberError::NotFinite)
649 );
650 }
651
652 #[test]
653 fn limits_profiles_and_builders() {
654 assert_eq!(JsonLimits::default(), JsonLimits::new());
655 assert!(JsonLimits::conservative().max_input_bytes < JsonLimits::new().max_input_bytes);
656 assert!(JsonLimits::permissive().max_input_bytes > JsonLimits::new().max_input_bytes);
657
658 let tuned = JsonLimits::new()
659 .with_max_depth(8)
660 .with_max_input_bytes(1024)
661 .with_max_string_bytes(16)
662 .with_max_total_nodes(32);
663 assert_eq!(tuned.max_depth, 8);
664 assert_eq!(tuned.max_input_bytes, 1024);
665 assert_eq!(tuned.max_string_bytes, 16);
666 assert_eq!(tuned.max_total_nodes, 32);
667 }
668
669 #[test]
670 fn error_display_covers_each_kind() {
671 let cases: &[(&str, &str)] = &[
673 ("", "unexpected end of input"),
674 ("@", "unexpected byte"),
675 ("\"a\\xb\"", "invalid escape sequence"),
676 ("\"\\uZZZZ\"", "invalid unicode escape"),
677 ("\"\\uD800\"", "unpaired UTF-16 surrogate"),
678 ("01", "invalid number"),
679 ("{\"a\":1,\"a\":2}", "duplicate object key"),
680 ("true false", "trailing data after JSON value"),
681 ];
682 for (input, expected) in cases {
683 let err = parse_str(input).unwrap_err();
684 assert!(
685 err.to_string().contains(expected),
686 "input {input:?} -> {err} (expected to contain {expected:?})"
687 );
688 }
689
690 let ctrl = parse(b"\"\x01\"").unwrap_err();
692 assert!(ctrl.to_string().contains("unescaped control character"));
693
694 let utf8 = parse(b"\xff").unwrap_err();
696 assert!(utf8.to_string().contains("invalid UTF-8"));
697 }
698
699 #[test]
700 fn error_accessors_and_limit_display_with_path() {
701 let limits = JsonLimits::new().with_max_depth(1);
702 let err = parse_with_limits(b"[[1]]", limits).unwrap_err();
703 assert_eq!(
704 err.kind(),
705 &JsonErrorKind::LimitExceeded(JsonLimitKind::Depth)
706 );
707 assert!(err.offset() >= 1);
708 assert_eq!(err.line(), 1);
709 assert!(err.column() >= 1);
710 let shown = err.to_string();
711 assert!(shown.contains("limit exceeded: nesting depth"));
712 assert!(shown.contains("path: $"));
713 assert_eq!(JsonLimitKind::Depth.as_str(), "nesting depth");
714 }
715
716 #[test]
717 fn path_display_formats_keys_and_indices() {
718 let path = JsonPath::from_segments(vec![
719 JsonPathSegment::Key("users".to_string()),
720 JsonPathSegment::Index(3),
721 JsonPathSegment::Key("email".to_string()),
722 ]);
723 assert_eq!(path.to_string(), "$.users[3].email");
724 assert_eq!(path.segments().len(), 3);
725 assert_eq!(JsonPath::default().to_string(), "$");
726 }
727
728 #[test]
729 fn number_error_display_is_distinct() {
730 assert_eq!(
731 JsonNumberError::OutOfRange.to_string(),
732 "number out of range for target type"
733 );
734 assert_eq!(
735 JsonNumberError::NotAnInteger.to_string(),
736 "number is not an integer"
737 );
738 assert_eq!(
739 JsonNumberError::NotFinite.to_string(),
740 "number is not finite"
741 );
742 assert_eq!(
743 JsonNumberError::InvalidNumber.to_string(),
744 "not a valid JSON number"
745 );
746 }
747
748 #[test]
749 fn writer_serializes_all_branches() {
750 let mut obj = JsonObject::new();
751 obj.insert("off".to_string(), JsonValue::Bool(false));
752 obj.insert(
753 "esc".to_string(),
754 JsonValue::String("\u{08}\u{0C}\n\r\t\u{1F}".to_string()),
756 );
757 obj.insert(
758 "arr".to_string(),
759 JsonValue::Array(vec![JsonValue::Null, JsonValue::Bool(true)]),
760 );
761 let value = JsonValue::Object(obj);
762
763 let s = to_compact_string(&value);
764 assert_eq!(parse_str(&s).unwrap(), value);
767 assert_eq!(to_compact_vec(&value), s.clone().into_bytes());
768 assert!(s.starts_with("{\"off\":false,"));
769 assert!(s.ends_with(",\"arr\":[null,true]}"));
770 }
771
772 #[cfg(feature = "std")]
773 #[test]
774 fn errors_implement_std_error() {
775 fn assert_error<E: std::error::Error>(_: &E) {}
776 let parse_err = parse_str("").unwrap_err();
777 assert_error(&parse_err);
778 let num_err = JsonNumber::new("1.5").unwrap().to_i64().unwrap_err();
779 assert_error(&num_err);
780 }
781}