1use std::cell::Cell;
13use std::fmt;
14
15use serde_json::{Map, Number, Value};
16
17use crate::instance::{ArrayView, Instance, Kind, ObjectView, View, str_eq};
18
19const MAX_DEPTH: usize = 127;
21
22#[derive(Clone, Copy)]
27struct Node {
28 kind: Kind,
29 flags: u8,
30 len: u32,
31 data: u64,
32}
33
34const NUM_U64: u8 = 0;
35const NUM_I64: u8 = 1;
36const NUM_F64: u8 = 2;
37
38const STR_SOURCE: u8 = 0;
40const STR_TEXT: u8 = 1;
42
43impl Node {
44 #[inline(always)]
45 const fn new(kind: Kind, flags: u8, len: u32, data: u64) -> Node {
46 Node { kind, flags, len, data }
47 }
48}
49
50pub struct JsonDocument<'s> {
52 source: &'s str,
53 nodes: Box<[Node]>,
54 root: Node,
55 text: Box<str>,
57}
58
59#[derive(Clone, Debug, PartialEq, Eq)]
61pub struct JsonParseError {
62 offset: usize,
63 message: &'static str,
64}
65
66impl JsonParseError {
67 pub fn offset(&self) -> usize {
69 self.offset
70 }
71
72 pub fn message(&self) -> &str {
74 self.message
75 }
76}
77
78impl fmt::Display for JsonParseError {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 write!(f, "{} at byte {}", self.message, self.offset)
81 }
82}
83
84impl std::error::Error for JsonParseError {}
85
86impl<'s> JsonDocument<'s> {
87 pub fn parse(source: &'s str) -> Result<JsonDocument<'s>, JsonParseError> {
91 let mut parser = Parser::new(source, BUFFERS.take().unwrap_or_default());
92 let root = parser.parse();
93 let document = root.map(|root| JsonDocument {
95 source,
96 nodes: parser.nodes.as_slice().into(),
97 root,
98 text: parser.text.as_str().into(),
99 });
100 let Parser { mut nodes, mut scratch, mut frames, mut text, .. } = parser;
101 if nodes.capacity() <= MAX_KEPT_NODES && text.capacity() <= MAX_KEPT_TEXT {
102 nodes.clear();
103 scratch.clear();
104 frames.clear();
105 text.clear();
106 BUFFERS.set(Some(Buffers { nodes, scratch, frames, text }));
107 }
108 document
109 }
110
111 #[inline]
113 pub fn root(&self) -> JsonDocumentValue<'_> {
114 JsonDocumentValue { doc: self.erase(), node: &self.root }
115 }
116
117 pub fn to_value(&self) -> Value {
119 self.root().to_value()
120 }
121
122 #[inline(always)]
124 fn erase<'d>(&'d self) -> &'d JsonDocument<'d> {
125 self
126 }
127
128 #[inline(always)]
129 fn str_of(&self, n: &Node) -> &str {
130 let (offset, len) = (n.data as usize, n.len as usize);
131 let buffer = if n.flags == STR_TEXT { &*self.text } else { self.source };
132 debug_assert!(buffer.is_char_boundary(offset) && buffer.is_char_boundary(offset + len));
133 unsafe { buffer.get_unchecked(offset..offset + len) }
135 }
136
137 #[inline(always)]
138 fn children(&self, n: &Node, count: usize) -> &[Node] {
139 let start = n.data as usize;
140 debug_assert!(start + count <= self.nodes.len());
141 unsafe { self.nodes.get_unchecked(start..start + count) }
143 }
144
145 #[inline(always)]
147 fn pairs(&self, n: &Node) -> &[[Node; 2]] {
148 let items = self.children(n, 2 * n.len as usize);
149 unsafe { std::slice::from_raw_parts(items.as_ptr().cast::<[Node; 2]>(), n.len as usize) }
151 }
152}
153
154impl fmt::Debug for JsonDocument<'_> {
155 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156 f.debug_struct("JsonDocument").field("nodes", &self.nodes.len()).finish()
157 }
158}
159
160#[derive(Clone, Copy)]
162pub struct JsonDocumentValue<'d> {
163 doc: &'d JsonDocument<'d>,
164 node: &'d Node,
165}
166
167#[derive(Clone, Copy)]
169pub struct JsonDocumentArray<'d> {
170 doc: &'d JsonDocument<'d>,
171 items: &'d [Node],
172}
173
174#[derive(Clone, Copy)]
176pub struct JsonDocumentObject<'d> {
177 doc: &'d JsonDocument<'d>,
178 pairs: &'d [[Node; 2]],
180}
181
182impl<'d> JsonDocumentValue<'d> {
183 #[inline(always)]
184 fn number(n: &Node) -> Number {
185 match n.flags {
186 NUM_U64 => Number::from(n.data),
187 NUM_I64 => Number::from(n.data as i64),
188 _ => Number::from_f64(f64::from_bits(n.data)).unwrap_or_else(|| Number::from(0)),
190 }
191 }
192
193 pub fn to_value(self) -> Value {
195 match self.view() {
196 View::Null => Value::Null,
197 View::Bool(b) => Value::Bool(b),
198 View::Number(n) => Value::Number(n),
199 View::String(s) => Value::String(s.to_owned()),
200 View::Array(a) => Value::Array(a.iter().map(JsonDocumentValue::to_value).collect()),
201 View::Object(o) => {
202 let mut map = Map::with_capacity(o.len());
203 for (k, v) in o.iter() {
204 map.insert(k.to_owned(), v.to_value());
205 }
206 Value::Object(map)
207 }
208 }
209 }
210}
211
212impl<'d> Instance<'d> for JsonDocumentValue<'d> {
213 type Array = JsonDocumentArray<'d>;
214 type Object = JsonDocumentObject<'d>;
215
216 #[inline(always)]
217 fn view(self) -> View<'d, Self> {
218 let (doc, n) = (self.doc, self.node);
219 match n.kind {
220 Kind::Null => View::Null,
221 Kind::Bool => View::Bool(n.data != 0),
222 Kind::Number => View::Number(Self::number(n)),
223 Kind::String => View::String(doc.str_of(n)),
224 Kind::Array => View::Array(JsonDocumentArray { doc, items: doc.children(n, n.len as usize) }),
225 Kind::Object => View::Object(JsonDocumentObject { doc, pairs: doc.pairs(n) }),
226 }
227 }
228
229 #[inline(always)]
230 fn kind(self) -> Kind {
231 self.node.kind
232 }
233}
234
235impl<'d> ArrayView<'d> for JsonDocumentArray<'d> {
236 type Item = JsonDocumentValue<'d>;
237
238 #[inline(always)]
239 fn len(self) -> usize {
240 self.items.len()
241 }
242
243 #[inline(always)]
244 fn get(self, index: usize) -> JsonDocumentValue<'d> {
245 JsonDocumentValue { doc: self.doc, node: &self.items[index] }
246 }
247
248 #[inline(always)]
249 fn iter(self) -> impl Iterator<Item = JsonDocumentValue<'d>> {
250 let doc = self.doc;
251 self.items.iter().map(move |node| JsonDocumentValue { doc, node })
252 }
253
254 #[inline(always)]
255 fn tail(self, start: usize) -> impl Iterator<Item = JsonDocumentValue<'d>> {
256 let doc = self.doc;
257 self.items.get(start..).unwrap_or_default().iter().map(move |node| JsonDocumentValue { doc, node })
258 }
259}
260
261impl<'d> ObjectView<'d> for JsonDocumentObject<'d> {
262 type Item = JsonDocumentValue<'d>;
263
264 #[inline(always)]
265 fn len(self) -> usize {
266 self.pairs.len()
267 }
268
269 #[inline]
270 fn get(self, name: &str) -> Option<JsonDocumentValue<'d>> {
271 let doc = self.doc;
272 self.pairs.iter().find(|[k, _]| str_eq(doc.str_of(k), name)).map(|[_, v]| JsonDocumentValue { doc, node: v })
273 }
274
275 #[inline]
276 fn contains_key(self, name: &str) -> bool {
277 let doc = self.doc;
278 self.pairs.iter().any(|[k, _]| str_eq(doc.str_of(k), name))
279 }
280
281 #[inline(always)]
282 fn iter(self) -> impl Iterator<Item = (&'d str, JsonDocumentValue<'d>)> {
283 let doc = self.doc;
284 self.pairs.iter().map(move |[k, v]| (doc.str_of(k), JsonDocumentValue { doc, node: v }))
285 }
286
287 #[inline(always)]
288 fn values(self) -> impl Iterator<Item = JsonDocumentValue<'d>> {
289 let doc = self.doc;
290 self.pairs.iter().map(move |[_, v]| JsonDocumentValue { doc, node: v })
291 }
292}
293
294#[derive(Default)]
298struct Buffers {
299 nodes: Vec<Node>,
300 scratch: Vec<Node>,
301 frames: Vec<Frame>,
302 text: String,
303}
304
305thread_local! {
306 static BUFFERS: Cell<Option<Buffers>> = const { Cell::new(None) };
308}
309
310const MAX_KEPT_NODES: usize = 1 << 20;
312const MAX_KEPT_TEXT: usize = 1 << 24;
314
315#[derive(Clone, Copy)]
317struct Frame {
318 start: u32,
319 object: bool,
320}
321
322struct Parser<'s> {
323 source: &'s str,
324 b: &'s [u8],
325 i: usize,
326 nodes: Vec<Node>,
328 scratch: Vec<Node>,
330 frames: Vec<Frame>,
331 text: String,
332}
333
334#[inline(always)]
336const fn eq_bytes(w: u64, n: u8) -> u64 {
337 let x = w ^ (0x0101_0101_0101_0101 * n as u64);
338 x.wrapping_sub(0x0101_0101_0101_0101) & !x & 0x8080_8080_8080_8080
339}
340
341#[inline(always)]
343const fn control_bytes(w: u64) -> u64 {
344 w.wrapping_sub(0x2020_2020_2020_2020) & !w & 0x8080_8080_8080_8080
345}
346
347impl<'s> Parser<'s> {
348 fn new(source: &'s str, buffers: Buffers) -> Parser<'s> {
349 Parser {
350 source,
351 b: source.as_bytes(),
352 i: 0,
353 nodes: buffers.nodes,
354 scratch: buffers.scratch,
355 frames: buffers.frames,
356 text: buffers.text,
357 }
358 }
359
360 #[cold]
361 fn error<T>(&self, message: &'static str) -> Result<T, JsonParseError> {
362 Err(JsonParseError { offset: self.i, message })
363 }
364
365 #[inline(always)]
366 fn skip_ws(&mut self) {
367 while let Some(&c) = self.b.get(self.i) {
368 if !matches!(c, b' ' | b'\n' | b'\r' | b'\t') {
369 break;
370 }
371 self.i += 1;
372 }
373 }
374
375 #[inline(always)]
376 fn peek(&self) -> Option<u8> {
377 self.b.get(self.i).copied()
378 }
379
380 fn parse(&mut self) -> Result<Node, JsonParseError> {
382 if self.source.len() > u32::MAX as usize {
383 return self.error("document too large");
384 }
385 self.skip_ws();
386 'value: loop {
387 match self.peek() {
389 Some(b'{') => {
390 self.i += 1;
391 self.skip_ws();
392 if self.peek() == Some(b'}') {
393 self.i += 1;
394 self.check_depth()?;
395 self.scratch.push(Node::new(Kind::Object, 0, 0, 0));
396 } else {
397 self.open(true)?;
398 self.key()?;
399 continue 'value;
400 }
401 }
402 Some(b'[') => {
403 self.i += 1;
404 self.skip_ws();
405 if self.peek() == Some(b']') {
406 self.i += 1;
407 self.check_depth()?;
408 self.scratch.push(Node::new(Kind::Array, 0, 0, 0));
409 } else {
410 self.open(false)?;
411 continue 'value;
412 }
413 }
414 Some(b'"') => {
415 let n = self.string()?;
416 self.scratch.push(n);
417 }
418 Some(b't') => self.literal(b"true", Node::new(Kind::Bool, 0, 0, 1))?,
419 Some(b'f') => self.literal(b"false", Node::new(Kind::Bool, 0, 0, 0))?,
420 Some(b'n') => self.literal(b"null", Node::new(Kind::Null, 0, 0, 0))?,
421 Some(b'-' | b'0'..=b'9') => {
422 let n = self.number()?;
423 self.scratch.push(n);
424 }
425 Some(_) => return self.error("expected a value"),
426 None => return self.error("unexpected end of input"),
427 }
428 loop {
430 let Some(&frame) = self.frames.last() else {
431 self.skip_ws();
432 if self.i != self.b.len() {
433 return self.error("trailing characters");
434 }
435 return Ok(self.scratch[0]);
436 };
437 self.skip_ws();
438 match self.peek() {
439 Some(b',') => {
440 self.i += 1;
441 self.skip_ws();
442 if frame.object {
443 self.key()?;
444 }
445 continue 'value;
446 }
447 Some(b'}') if frame.object => {
448 self.i += 1;
449 self.close(frame);
450 }
451 Some(b']') if !frame.object => {
452 self.i += 1;
453 self.close(frame);
454 }
455 Some(_) => {
456 return self.error(if frame.object { "expected ',' or '}'" } else { "expected ',' or ']'" });
457 }
458 None => return self.error("unexpected end of input"),
459 }
460 }
461 }
462 }
463
464 #[inline(always)]
465 fn open(&mut self, object: bool) -> Result<(), JsonParseError> {
466 self.check_depth()?;
467 self.frames.push(Frame { start: self.scratch.len() as u32, object });
468 Ok(())
469 }
470
471 #[inline(always)]
473 fn check_depth(&self) -> Result<(), JsonParseError> {
474 if self.frames.len() >= MAX_DEPTH { self.error("recursion limit exceeded") } else { Ok(()) }
475 }
476
477 #[inline(always)]
479 fn key(&mut self) -> Result<(), JsonParseError> {
480 if self.peek() != Some(b'"') {
481 return self.error("expected a property name");
482 }
483 let k = self.string()?;
484 self.scratch.push(k);
485 self.skip_ws();
486 if self.peek() != Some(b':') {
487 return self.error("expected ':'");
488 }
489 self.i += 1;
490 self.skip_ws();
491 Ok(())
492 }
493
494 #[inline(always)]
496 fn close(&mut self, frame: Frame) {
497 self.frames.pop();
498 let start = frame.start as usize;
499 if frame.object && self.scratch.len() - start > 2 {
500 self.dedupe(start);
501 }
502 let first = self.nodes.len() as u64;
503 let children = self.scratch.len() - start;
504 self.nodes.extend_from_slice(&self.scratch[start..]);
505 self.scratch.truncate(start);
506 let (kind, count) = if frame.object { (Kind::Object, children / 2) } else { (Kind::Array, children) };
507 self.scratch.push(Node::new(kind, 0, count as u32, first));
508 }
509
510 fn key_str(&self, n: &Node) -> &str {
511 let (offset, len) = (n.data as usize, n.len as usize);
512 if n.flags == STR_TEXT { &self.text[offset..offset + len] } else { &self.source[offset..offset + len] }
513 }
514
515 fn dedupe(&mut self, start: usize) {
518 let pairs = &self.scratch[start..];
519 let count = pairs.len() / 2;
520 let duplicate = if count <= 16 {
521 (1..count).any(|j| (0..j).any(|i| str_eq(self.key_str(&pairs[2 * i]), self.key_str(&pairs[2 * j]))))
522 } else {
523 let mut seen = std::collections::HashSet::with_capacity(count);
524 (0..count).any(|j| !seen.insert(self.key_str(&pairs[2 * j])))
525 };
526 if !duplicate {
527 return;
528 }
529 let mut kept: Vec<Node> = Vec::with_capacity(pairs.len());
530 for p in pairs.chunks_exact(2) {
531 let name = self.key_str(&p[0]);
532 match kept.chunks_exact(2).position(|q| self.key_str(&q[0]) == name) {
533 Some(at) => kept[2 * at + 1] = p[1],
534 None => kept.extend_from_slice(p),
535 }
536 }
537 self.scratch.truncate(start);
538 self.scratch.extend_from_slice(&kept);
539 }
540
541 #[inline(always)]
542 fn literal(&mut self, word: &[u8], node: Node) -> Result<(), JsonParseError> {
543 if self.b.get(self.i..self.i + word.len()) != Some(word) {
544 return self.error("expected a value");
545 }
546 self.i += word.len();
547 self.scratch.push(node);
548 Ok(())
549 }
550
551 #[inline(always)]
553 fn string(&mut self) -> Result<Node, JsonParseError> {
554 let start = self.i + 1;
555 let mut j = start;
556 let b = self.b;
557 while j + 8 <= b.len() {
559 let w = u64::from_le_bytes(b[j..j + 8].try_into().unwrap());
560 let special = eq_bytes(w, b'"') | eq_bytes(w, b'\\') | control_bytes(w);
561 if special != 0 {
562 j += (special.trailing_zeros() / 8) as usize;
563 return self.string_at(start, j);
564 }
565 j += 8;
566 }
567 while j < b.len() && !matches!(b[j], b'"' | b'\\' | 0..0x20) {
568 j += 1;
569 }
570 self.string_at(start, j)
571 }
572
573 #[inline(always)]
574 fn string_at(&mut self, start: usize, j: usize) -> Result<Node, JsonParseError> {
575 match self.b.get(j) {
576 Some(b'"') => {
577 self.i = j + 1;
578 Ok(Node::new(Kind::String, STR_SOURCE, (j - start) as u32, start as u64))
579 }
580 Some(b'\\') => self.escaped(start, j),
581 Some(_) => {
582 self.i = j;
583 self.error("control character in a string")
584 }
585 None => {
586 self.i = j;
587 self.error("unterminated string")
588 }
589 }
590 }
591
592 #[cold]
594 fn escaped(&mut self, start: usize, mut j: usize) -> Result<Node, JsonParseError> {
595 let offset = self.text.len();
596 let b = self.b;
597 let mut run = start;
598 loop {
599 match b.get(j) {
600 Some(b'"') => {
601 self.text.push_str(&self.source[run..j]);
602 self.i = j + 1;
603 let len = self.text.len() - offset;
604 return Ok(Node::new(Kind::String, STR_TEXT, len as u32, offset as u64));
605 }
606 Some(b'\\') => {
607 self.text.push_str(&self.source[run..j]);
608 let c = match b.get(j + 1) {
609 Some(b'"') => '"',
610 Some(b'\\') => '\\',
611 Some(b'/') => '/',
612 Some(b'b') => '\u{8}',
613 Some(b'f') => '\u{c}',
614 Some(b'n') => '\n',
615 Some(b'r') => '\r',
616 Some(b't') => '\t',
617 Some(b'u') => {
618 let (c, next) = self.unicode_escape(j)?;
619 self.text.push(c);
620 j = next;
621 run = j;
622 continue;
623 }
624 _ => {
625 self.i = j;
626 return self.error("invalid escape");
627 }
628 };
629 self.text.push(c);
630 j += 2;
631 run = j;
632 }
633 Some(0..0x20) => {
634 self.i = j;
635 return self.error("control character in a string");
636 }
637 Some(_) => j += 1,
638 None => {
639 self.i = j;
640 return self.error("unterminated string");
641 }
642 }
643 }
644 }
645
646 fn unicode_escape(&mut self, j: usize) -> Result<(char, usize), JsonParseError> {
648 let hex = |p: &Self, at: usize| -> Option<u32> {
649 let digits = p.b.get(at..at + 4)?;
650 let mut v = 0u32;
651 for &d in digits {
652 v = v * 16 + (d as char).to_digit(16)?;
653 }
654 Some(v)
655 };
656 let Some(u) = hex(self, j + 2) else {
657 self.i = j;
658 return self.error("invalid \\u escape");
659 };
660 match u {
661 0xD800..=0xDBFF => {
662 let low = (self.b.get(j + 6) == Some(&b'\\') && self.b.get(j + 7) == Some(&b'u'))
663 .then(|| hex(self, j + 8))
664 .flatten();
665 match low {
666 Some(l @ 0xDC00..=0xDFFF) => {
667 let c = 0x10000 + ((u - 0xD800) << 10) + (l - 0xDC00);
668 Ok((char::from_u32(c).unwrap(), j + 12))
669 }
670 _ => {
671 self.i = j;
672 self.error("lone leading surrogate in hex escape")
673 }
674 }
675 }
676 0xDC00..=0xDFFF => {
677 self.i = j;
678 self.error("lone trailing surrogate in hex escape")
679 }
680 _ => Ok((char::from_u32(u).unwrap(), j + 6)),
681 }
682 }
683
684 #[inline(always)]
687 fn number(&mut self) -> Result<Node, JsonParseError> {
688 let b = self.b;
689 let start = self.i;
690 let mut j = start;
691 let negative = b[j] == b'-';
692 if negative {
693 j += 1;
694 }
695 let mut value: u64 = 0;
696 let mut overflow = false;
697 match b.get(j) {
698 Some(b'0') => j += 1,
699 Some(b'1'..=b'9') => {
700 while let Some(&d @ b'0'..=b'9') = b.get(j) {
701 match value.checked_mul(10).and_then(|v| v.checked_add((d - b'0') as u64)) {
702 Some(v) => value = v,
703 None => overflow = true,
704 }
705 j += 1;
706 }
707 }
708 _ => {
709 self.i = j;
710 return self.error("invalid number");
711 }
712 }
713 let mut float = false;
714 if b.get(j) == Some(&b'.') {
715 j += 1;
716 if !matches!(b.get(j), Some(b'0'..=b'9')) {
717 self.i = j;
718 return self.error("invalid number");
719 }
720 while matches!(b.get(j), Some(b'0'..=b'9')) {
721 j += 1;
722 }
723 float = true;
724 }
725 if matches!(b.get(j), Some(b'e' | b'E')) {
726 j += 1;
727 if matches!(b.get(j), Some(b'+' | b'-')) {
728 j += 1;
729 }
730 if !matches!(b.get(j), Some(b'0'..=b'9')) {
731 self.i = j;
732 return self.error("invalid number");
733 }
734 while matches!(b.get(j), Some(b'0'..=b'9')) {
735 j += 1;
736 }
737 float = true;
738 }
739 self.i = j;
740 if !float && !overflow {
741 if !negative {
742 return Ok(Node::new(Kind::Number, NUM_U64, 0, value));
743 }
744 if value != 0 && value <= i64::MAX as u64 + 1 {
746 return Ok(Node::new(Kind::Number, NUM_I64, 0, (value as i64).wrapping_neg() as u64));
747 }
748 }
749 let f: f64 = self.source[start..j].parse().unwrap_or(f64::INFINITY);
750 if !f.is_finite() {
751 self.i = start;
752 return self.error("number out of range");
753 }
754 Ok(Node::new(Kind::Number, NUM_F64, 0, f.to_bits()))
755 }
756}
757
758#[cfg(test)]
759mod tests {
760 use super::*;
761
762 fn same(text: &str) {
763 let expected: Value = serde_json::from_str(text).unwrap();
764 let document = JsonDocument::parse(text).unwrap_or_else(|e| panic!("{text}: {e}"));
765 assert_eq!(document.to_value(), expected, "{text}");
766 assert_eq!(serde_json::to_string(&document.to_value()).unwrap(), serde_json::to_string(&expected).unwrap());
768 }
769
770 fn both_reject(text: &str) {
771 assert!(serde_json::from_str::<Value>(text).is_err(), "serde_json accepts {text}");
772 assert!(JsonDocument::parse(text).is_err(), "accepted {text}");
773 }
774
775 #[test]
776 fn values_match_serde_json() {
777 for text in [
778 "null",
779 " true ",
780 "false",
781 "0",
782 "-0",
783 "-0.0",
784 "1",
785 "-1",
786 "18446744073709551615",
787 "18446744073709551616",
788 "-9223372036854775808",
789 "-9223372036854775809",
790 "1.5",
791 "1e3",
792 "1E+3",
793 "1.0e-3",
794 "123456789012345678901234567890",
795 "2.2250738585072014e-308",
796 "\"\"",
797 "\"plain text, longer than eight bytes\"",
798 "\"caf\u{e9} \u{1f600}\"",
799 r#""esc \" \\ \/ \b \f \n \r \t é 😀 end""#,
800 r#""\u0000""#,
801 "[]",
802 "{}",
803 "[1, [2, [3, []]], {}]",
804 r#"{"a": 1, "b": [true, null], "c": {"d": "e"}}"#,
805 r#"{"a": 1, "b": 2, "a": 3}"#,
806 r#"{"x": 1, "y": 2, "x": {"z": 1}, "y": 4, "w": 5}"#,
807 ] {
808 same(text);
809 }
810 let many: String =
811 format!("{{{}}}", (0..40).map(|i| format!("\"k{}\": {i}", i % 25)).collect::<Vec<_>>().join(","));
812 same(&many);
813 }
814
815 #[test]
816 fn doubles_are_correctly_rounded() {
817 let text = "-90.50242899999999";
819 let d = JsonDocument::parse(text).unwrap();
820 assert_eq!(d.to_value().as_f64().unwrap().to_bits(), text.parse::<f64>().unwrap().to_bits());
821 }
822
823 #[test]
824 fn rejects_what_serde_json_rejects() {
825 for text in [
826 "",
827 " ",
828 "nul",
829 "tru",
830 "01",
831 "-",
832 "1.",
833 ".5",
834 "1e",
835 "+1",
836 "1e400",
837 "[1,]",
838 "[1 2]",
839 "{\"a\" 1}",
840 "{\"a\": 1,}",
841 "{a: 1}",
842 "\"unterminated",
843 "\"tab\there\"",
844 r#""\x""#,
845 r#""\ud800""#,
846 r#""\udc00""#,
847 r#""\ud800A""#,
848 "[1] 2",
849 "[",
850 "{",
851 ] {
852 both_reject(text);
853 }
854 }
855
856 #[test]
857 fn depth_limit() {
858 for inner in ["", "1"] {
859 let nest = |n: usize| format!("{}{inner}{}", "[".repeat(n), "]".repeat(n));
860 assert!(JsonDocument::parse(&nest(MAX_DEPTH)).is_ok());
861 assert!(JsonDocument::parse(&nest(MAX_DEPTH + 1)).is_err());
862 assert!(serde_json::from_str::<Value>(&nest(MAX_DEPTH)).is_ok());
863 assert!(serde_json::from_str::<Value>(&nest(MAX_DEPTH + 1)).is_err());
864 }
865 }
866
867 #[test]
868 fn reads_in_place() {
869 let d = JsonDocument::parse(r#"{"a": [1, "x\n"], "b": {"c": null}}"#).unwrap();
870 let View::Object(o) = d.root().view() else { panic!() };
871 assert_eq!(o.len(), 2);
872 assert!(o.contains_key("b") && !o.contains_key("c"));
873 let View::Array(a) = o.get("a").unwrap().view() else { panic!() };
874 assert_eq!(a.len(), 2);
875 assert!(matches!(a.get(1).view(), View::String("x\n")));
876 assert_eq!(a.tail(1).count(), 1);
877 assert_eq!(a.tail(5).count(), 0);
878 assert_eq!(o.iter().map(|(k, _)| k).collect::<Vec<_>>(), ["a", "b"]);
879 }
880}