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