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