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