1use std::borrow::Cow;
2use std::fmt;
3use std::io::{Read, Write};
4use std::ops::{Index, IndexMut};
5
6
7#[derive(Clone, Debug, PartialEq)]
8pub enum JsonNumber {
9 I64(i64),
10 U64(u64),
11 F64(f64),
12}
13
14
15impl JsonNumber {
16 pub fn is_i64(&self) -> bool {
17 matches!(self, Self::I64(_))
18 }
19
20 pub fn is_u64(&self) -> bool {
21 matches!(self, Self::U64(_))
22 }
23
24 pub fn is_f64(&self) -> bool {
25 matches!(self, Self::F64(_))
26 }
27
28 pub fn as_i64(&self) -> Option<i64> {
29 match self {
30 Self::I64(value) => Some(*value),
31 Self::U64(value) => (*value <= i64::MAX as u64).then_some(*value as i64),
32 Self::F64(_) => None,
33 }
34 }
35
36 pub fn as_u64(&self) -> Option<u64> {
37 match self {
38 Self::I64(value) => (*value >= 0).then_some(*value as u64),
39 Self::U64(value) => Some(*value),
40 Self::F64(_) => None,
41 }
42 }
43
44 pub fn as_f64(&self) -> Option<f64> {
45 match self {
46 Self::I64(value) => Some(*value as f64),
47 Self::U64(value) => Some(*value as f64),
48 Self::F64(value) => Some(*value),
49 }
50 }
51
52 pub fn from_f64(value: f64) -> Option<Self> {
53 value.is_finite().then_some(Self::F64(value))
54 }
55}
56
57#[derive(Clone, Debug, PartialEq)]
58pub enum JsonValue {
59 Null,
60 Bool(bool),
61 Number(JsonNumber),
62 String(String),
63 Array(Vec<JsonValue>),
64 Object(Vec<(String, JsonValue)>),
65}
66
67pub type Value = JsonValue;
68pub type Number = JsonNumber;
69pub type Map = Vec<(String, JsonValue)>;
70
71#[derive(Clone, Debug, PartialEq)]
72pub enum BorrowedJsonValue<'a> {
73 Null,
74 Bool(bool),
75 Number(JsonNumber),
76 String(Cow<'a, str>),
77 Array(Vec<BorrowedJsonValue<'a>>),
78 Object(Vec<(Cow<'a, str>, BorrowedJsonValue<'a>)>),
79}
80
81#[derive(Clone, Debug, PartialEq, Eq)]
82pub struct CompiledObjectSchema {
83 fields: Vec<CompiledField>,
84 capacity_hint: usize,
85}
86
87#[derive(Clone, Debug, PartialEq, Eq)]
88pub struct CompiledRowSchema {
89 object: CompiledObjectSchema,
90 row_capacity_hint: usize,
91}
92
93#[derive(Clone, Debug, PartialEq, Eq)]
94pub struct JsonTape {
95 pub tokens: Vec<TapeToken>,
96}
97
98#[derive(Clone, Debug, PartialEq, Eq)]
99pub struct TapeToken {
100 pub kind: TapeTokenKind,
101 pub start: usize,
102 pub end: usize,
103 pub parent: Option<usize>,
104}
105
106#[derive(Clone, Copy, Debug, PartialEq, Eq)]
107pub enum TapeTokenKind {
108 Null,
109 Bool,
110 Number,
111 String,
112 Key,
113 Array,
114 Object,
115}
116
117#[derive(Clone, Copy, Debug, PartialEq, Eq)]
118pub struct TapeValue<'a> {
119 tape: &'a JsonTape,
120 input: &'a str,
121 index: usize,
122}
123
124#[derive(Clone, Debug, PartialEq, Eq)]
125pub struct TapeObjectIndex {
126 buckets: Vec<Vec<(u64, usize, usize)>>,
127}
128
129#[derive(Clone, Copy, Debug)]
130pub struct IndexedTapeObject<'a> {
131 object: TapeValue<'a>,
132 index: &'a TapeObjectIndex,
133}
134
135#[derive(Clone, Debug, PartialEq, Eq)]
136pub struct CompiledTapeKey {
137 key: String,
138 hash: u64,
139}
140
141#[derive(Clone, Debug, PartialEq, Eq)]
142pub struct CompiledTapeKeys {
143 keys: Vec<CompiledTapeKey>,
144}
145
146#[derive(Clone, Debug, PartialEq, Eq)]
147struct CompiledField {
148 key: String,
149 rendered_prefix: Vec<u8>,
150}
151
152#[derive(Clone, Debug, PartialEq, Eq)]
153pub enum JsonError {
154 NonFiniteNumber,
155 Io,
156}
157
158#[derive(Clone, Debug, PartialEq, Eq)]
159pub enum JsonParseError {
160 InvalidUtf8,
161 UnexpectedEnd,
162 UnexpectedTrailingCharacters(usize),
163 UnexpectedCharacter { index: usize, found: char },
164 InvalidLiteral { index: usize },
165 InvalidNumber { index: usize },
166 InvalidEscape { index: usize },
167 InvalidUnicodeEscape { index: usize },
168 InvalidUnicodeScalar { index: usize },
169 ExpectedColon { index: usize },
170 ExpectedCommaOrEnd { index: usize, context: &'static str },
171}
172
173impl fmt::Display for JsonError {
174 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175 match self {
176 Self::NonFiniteNumber => {
177 f.write_str("cannot serialize non-finite floating-point value")
178 }
179 Self::Io => f.write_str("i/o error while serializing JSON"),
180 }
181 }
182}
183
184impl fmt::Display for JsonParseError {
185 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186 match self {
187 Self::InvalidUtf8 => f.write_str("input is not valid UTF-8"),
188 Self::UnexpectedEnd => f.write_str("unexpected end of JSON input"),
189 Self::UnexpectedTrailingCharacters(index) => {
190 write!(f, "unexpected trailing characters at byte {index}")
191 }
192 Self::UnexpectedCharacter { index, found } => {
193 write!(f, "unexpected character '{found}' at byte {index}")
194 }
195 Self::InvalidLiteral { index } => write!(f, "invalid literal at byte {index}"),
196 Self::InvalidNumber { index } => write!(f, "invalid number at byte {index}"),
197 Self::InvalidEscape { index } => write!(f, "invalid escape sequence at byte {index}"),
198 Self::InvalidUnicodeEscape { index } => {
199 write!(f, "invalid unicode escape at byte {index}")
200 }
201 Self::InvalidUnicodeScalar { index } => {
202 write!(f, "invalid unicode scalar at byte {index}")
203 }
204 Self::ExpectedColon { index } => write!(f, "expected ':' at byte {index}"),
205 Self::ExpectedCommaOrEnd { index, context } => {
206 write!(f, "expected ',' or end of {context} at byte {index}")
207 }
208 }
209 }
210}
211
212impl std::error::Error for JsonError {}
213impl std::error::Error for JsonParseError {}
214
215impl JsonValue {
216 pub fn object(entries: Vec<(impl Into<String>, JsonValue)>) -> Self {
217 Self::Object(
218 entries
219 .into_iter()
220 .map(|(key, value)| (key.into(), value))
221 .collect(),
222 )
223 }
224
225 pub fn array(values: Vec<JsonValue>) -> Self {
226 Self::Array(values)
227 }
228
229 pub fn to_json_string(&self) -> Result<String, JsonError> {
230 let mut out = Vec::with_capacity(initial_json_capacity(self));
231 write_json_value(&mut out, self)?;
232 Ok(unsafe { String::from_utf8_unchecked(out) })
233 }
234
235 pub fn push_field(&mut self, key: impl Into<String>, value: impl Into<JsonValue>) {
236 match self {
237 Self::Object(entries) => entries.push((key.into(), value.into())),
238 _ => panic!("push_field called on non-object JSON value"),
239 }
240 }
241
242 pub fn push_item(&mut self, value: impl Into<JsonValue>) {
243 match self {
244 Self::Array(values) => values.push(value.into()),
245 _ => panic!("push_item called on non-array JSON value"),
246 }
247 }
248
249 pub fn is_null(&self) -> bool {
250 self.as_null().is_some()
251 }
252
253 pub fn as_null(&self) -> Option<()> {
254 matches!(self, Self::Null).then_some(())
255 }
256
257 pub fn is_boolean(&self) -> bool {
258 matches!(self, Self::Bool(_))
259 }
260
261 pub fn is_number(&self) -> bool {
262 matches!(self, Self::Number(_))
263 }
264
265 pub fn is_string(&self) -> bool {
266 matches!(self, Self::String(_))
267 }
268
269 pub fn is_array(&self) -> bool {
270 matches!(self, Self::Array(_))
271 }
272
273 pub fn is_object(&self) -> bool {
274 matches!(self, Self::Object(_))
275 }
276
277 pub fn as_bool(&self) -> Option<bool> {
278 match self {
279 Self::Bool(value) => Some(*value),
280 _ => None,
281 }
282 }
283
284 pub fn as_number(&self) -> Option<&JsonNumber> {
285 match self {
286 Self::Number(number) => Some(number),
287 _ => None,
288 }
289 }
290
291 pub fn is_i64(&self) -> bool {
292 self.as_number().is_some_and(JsonNumber::is_i64)
293 }
294
295 pub fn is_u64(&self) -> bool {
296 self.as_number().is_some_and(JsonNumber::is_u64)
297 }
298
299 pub fn is_f64(&self) -> bool {
300 self.as_number().is_some_and(JsonNumber::is_f64)
301 }
302
303 pub fn as_i64(&self) -> Option<i64> {
304 self.as_number().and_then(JsonNumber::as_i64)
305 }
306
307 pub fn as_u64(&self) -> Option<u64> {
308 self.as_number().and_then(JsonNumber::as_u64)
309 }
310
311 pub fn as_f64(&self) -> Option<f64> {
312 self.as_number().and_then(JsonNumber::as_f64)
313 }
314
315 pub fn as_str(&self) -> Option<&str> {
316 match self {
317 Self::String(value) => Some(value.as_str()),
318 _ => None,
319 }
320 }
321
322 pub fn as_array(&self) -> Option<&Vec<JsonValue>> {
323 match self {
324 Self::Array(values) => Some(values),
325 _ => None,
326 }
327 }
328
329 pub fn as_array_mut(&mut self) -> Option<&mut Vec<JsonValue>> {
330 match self {
331 Self::Array(values) => Some(values),
332 _ => None,
333 }
334 }
335
336 pub fn as_object(&self) -> Option<&Map> {
337 match self {
338 Self::Object(entries) => Some(entries),
339 _ => None,
340 }
341 }
342
343 pub fn as_object_mut(&mut self) -> Option<&mut Map> {
344 match self {
345 Self::Object(entries) => Some(entries),
346 _ => None,
347 }
348 }
349
350 pub fn get<I>(&self, index: I) -> Option<&JsonValue>
351 where
352 I: ValueIndex,
353 {
354 index.index_into(self)
355 }
356
357 pub fn get_mut<I>(&mut self, index: I) -> Option<&mut JsonValue>
358 where
359 I: ValueIndex,
360 {
361 index.index_into_mut(self)
362 }
363
364 pub fn len(&self) -> usize {
365 match self {
366 Self::Array(values) => values.len(),
367 Self::Object(entries) => entries.len(),
368 _ => 0,
369 }
370 }
371
372 pub fn is_empty(&self) -> bool {
373 self.len() == 0
374 }
375
376 pub fn as_i128(&self) -> Option<i128> {
377 self.as_i64().map(|v| v as i128)
378 }
379
380 pub fn as_u128(&self) -> Option<u128> {
381 self.as_u64().map(|v| v as u128)
382 }
383
384 pub fn as_f32(&self) -> Option<f32> {
385 self.as_f64().map(|v| v as f32)
386 }
387
388 pub fn get_index(&self, index: usize) -> Option<&JsonValue> {
389 match self {
390 Self::Array(values) => values.get(index),
391 _ => None,
392 }
393 }
394
395 pub fn get_index_mut(&mut self, index: usize) -> Option<&mut JsonValue> {
396 match self {
397 Self::Array(values) => values.get_mut(index),
398 _ => None,
399 }
400 }
401
402 pub fn take(&mut self) -> JsonValue {
403 std::mem::replace(self, JsonValue::Null)
404 }
405
406 pub fn pointer(&self, pointer: &str) -> Option<&JsonValue> {
407 if pointer.is_empty() {
408 return Some(self);
409 }
410 if !pointer.starts_with('/') {
411 return None;
412 }
413 let mut current = self;
414 for segment in pointer.split('/').skip(1) {
415 let token = decode_pointer_segment(segment);
416 current = match current {
417 JsonValue::Object(entries) => entries
418 .iter()
419 .find(|(key, _)| key == &token)
420 .map(|(_, value)| value)?,
421 JsonValue::Array(values) => values.get(token.parse::<usize>().ok()?)?,
422 _ => return None,
423 };
424 }
425 Some(current)
426 }
427
428 pub fn pointer_mut(&mut self, pointer: &str) -> Option<&mut JsonValue> {
429 if pointer.is_empty() {
430 return Some(self);
431 }
432 if !pointer.starts_with('/') {
433 return None;
434 }
435 let mut current = self;
436 for segment in pointer.split('/').skip(1) {
437 let token = decode_pointer_segment(segment);
438 current = match current {
439 JsonValue::Object(entries) => entries
440 .iter_mut()
441 .find(|(key, _)| key == &token)
442 .map(|(_, value)| value)?,
443 JsonValue::Array(values) => values.get_mut(token.parse::<usize>().ok()?)?,
444 _ => return None,
445 };
446 }
447 Some(current)
448 }
449
450 pub fn sort_all_objects(&mut self) {
451 match self {
452 JsonValue::Object(entries) => {
453 entries.sort_by(|a, b| a.0.cmp(&b.0));
454 for (_, value) in entries.iter_mut() {
455 value.sort_all_objects();
456 }
457 }
458 JsonValue::Array(values) => {
459 for value in values.iter_mut() {
460 value.sort_all_objects();
461 }
462 }
463 _ => {}
464 }
465 }
466}
467
468impl<'a> BorrowedJsonValue<'a> {
469 pub fn into_owned(self) -> JsonValue {
470 match self {
471 Self::Null => JsonValue::Null,
472 Self::Bool(value) => JsonValue::Bool(value),
473 Self::Number(value) => JsonValue::Number(value),
474 Self::String(value) => JsonValue::String(value.into_owned()),
475 Self::Array(values) => JsonValue::Array(
476 values
477 .into_iter()
478 .map(BorrowedJsonValue::into_owned)
479 .collect(),
480 ),
481 Self::Object(entries) => JsonValue::Object(
482 entries
483 .into_iter()
484 .map(|(key, value)| (key.into_owned(), value.into_owned()))
485 .collect(),
486 ),
487 }
488 }
489}
490
491impl CompiledObjectSchema {
492 pub fn new(keys: &[&str]) -> Self {
493 let mut fields = Vec::with_capacity(keys.len());
494 let mut capacity_hint = 2;
495 for (index, key) in keys.iter().enumerate() {
496 let mut rendered_prefix = Vec::with_capacity(key.len() + 4);
497 if index > 0 {
498 rendered_prefix.push(b',');
499 }
500 write_json_key(&mut rendered_prefix, key);
501 capacity_hint += rendered_prefix.len() + 8;
502 fields.push(CompiledField {
503 key: (*key).to_owned(),
504 rendered_prefix,
505 });
506 }
507 Self {
508 fields,
509 capacity_hint,
510 }
511 }
512
513 pub fn keys(&self) -> impl ExactSizeIterator<Item = &str> {
514 self.fields.iter().map(|field| field.key.as_str())
515 }
516
517 pub fn to_json_string<'a, I>(&self, values: I) -> Result<String, JsonError>
518 where
519 I: IntoIterator<Item = &'a JsonValue>,
520 {
521 let mut out = Vec::with_capacity(self.capacity_hint);
522 self.write_json_bytes(&mut out, values)?;
523 Ok(unsafe { String::from_utf8_unchecked(out) })
524 }
525
526 pub fn write_json_bytes<'a, I>(&self, out: &mut Vec<u8>, values: I) -> Result<(), JsonError>
527 where
528 I: IntoIterator<Item = &'a JsonValue>,
529 {
530 out.push(b'{');
531 let mut iter = values.into_iter();
532 for field in &self.fields {
533 let Some(value) = iter.next() else {
534 panic!(
535 "compiled object schema expected {} values",
536 self.fields.len()
537 );
538 };
539 out.extend_from_slice(&field.rendered_prefix);
540 write_json_value(out, value)?;
541 }
542 if iter.next().is_some() {
543 panic!(
544 "compiled object schema received more than {} values",
545 self.fields.len()
546 );
547 }
548 out.push(b'}');
549 Ok(())
550 }
551}
552
553impl CompiledRowSchema {
554 pub fn new(keys: &[&str]) -> Self {
555 let object = CompiledObjectSchema::new(keys);
556 let row_capacity_hint = object.capacity_hint;
557 Self {
558 object,
559 row_capacity_hint,
560 }
561 }
562
563 pub fn object_schema(&self) -> &CompiledObjectSchema {
564 &self.object
565 }
566
567 pub fn to_json_string<'a, R, I>(&self, rows: R) -> Result<String, JsonError>
568 where
569 R: IntoIterator<Item = I>,
570 I: IntoIterator<Item = &'a JsonValue>,
571 {
572 let iter = rows.into_iter();
573 let (lower, _) = iter.size_hint();
574 let mut out = Vec::with_capacity(2 + lower.saturating_mul(self.row_capacity_hint + 1));
575 self.write_json_bytes_from_iter(&mut out, iter)?;
576 Ok(unsafe { String::from_utf8_unchecked(out) })
577 }
578
579 pub fn write_json_bytes<'a, R, I>(&self, out: &mut Vec<u8>, rows: R) -> Result<(), JsonError>
580 where
581 R: IntoIterator<Item = I>,
582 I: IntoIterator<Item = &'a JsonValue>,
583 {
584 self.write_json_bytes_from_iter(out, rows.into_iter())
585 }
586
587 pub fn write_row_json_bytes<'a, I>(&self, out: &mut Vec<u8>, values: I) -> Result<(), JsonError>
588 where
589 I: IntoIterator<Item = &'a JsonValue>,
590 {
591 self.object.write_json_bytes(out, values)
592 }
593
594 fn write_json_bytes_from_iter<'a, R, I>(
595 &self,
596 out: &mut Vec<u8>,
597 mut rows: R,
598 ) -> Result<(), JsonError>
599 where
600 R: Iterator<Item = I>,
601 I: IntoIterator<Item = &'a JsonValue>,
602 {
603 out.push(b'[');
604 if let Some(first_row) = rows.next() {
605 self.object.write_json_bytes(out, first_row)?;
606 for row in rows {
607 out.push(b',');
608 self.object.write_json_bytes(out, row)?;
609 }
610 }
611 out.push(b']');
612 Ok(())
613 }
614}
615
616impl From<bool> for JsonValue {
617 fn from(value: bool) -> Self {
618 Self::Bool(value)
619 }
620}
621
622impl From<String> for JsonValue {
623 fn from(value: String) -> Self {
624 Self::String(value)
625 }
626}
627
628impl From<&str> for JsonValue {
629 fn from(value: &str) -> Self {
630 Self::String(value.to_owned())
631 }
632}
633
634impl From<i8> for JsonValue {
635 fn from(value: i8) -> Self {
636 Self::Number(JsonNumber::I64(value as i64))
637 }
638}
639
640impl From<i16> for JsonValue {
641 fn from(value: i16) -> Self {
642 Self::Number(JsonNumber::I64(value as i64))
643 }
644}
645
646impl From<i32> for JsonValue {
647 fn from(value: i32) -> Self {
648 Self::Number(JsonNumber::I64(value as i64))
649 }
650}
651
652impl From<i64> for JsonValue {
653 fn from(value: i64) -> Self {
654 Self::Number(JsonNumber::I64(value))
655 }
656}
657
658impl From<isize> for JsonValue {
659 fn from(value: isize) -> Self {
660 Self::Number(JsonNumber::I64(value as i64))
661 }
662}
663
664impl From<u8> for JsonValue {
665 fn from(value: u8) -> Self {
666 Self::Number(JsonNumber::U64(value as u64))
667 }
668}
669
670impl From<u16> for JsonValue {
671 fn from(value: u16) -> Self {
672 Self::Number(JsonNumber::U64(value as u64))
673 }
674}
675
676impl From<u32> for JsonValue {
677 fn from(value: u32) -> Self {
678 Self::Number(JsonNumber::U64(value as u64))
679 }
680}
681
682impl From<u64> for JsonValue {
683 fn from(value: u64) -> Self {
684 Self::Number(JsonNumber::U64(value))
685 }
686}
687
688impl From<usize> for JsonValue {
689 fn from(value: usize) -> Self {
690 Self::Number(JsonNumber::U64(value as u64))
691 }
692}
693
694impl From<f32> for JsonValue {
695 fn from(value: f32) -> Self {
696 Self::Number(JsonNumber::F64(value as f64))
697 }
698}
699
700impl From<f64> for JsonValue {
701 fn from(value: f64) -> Self {
702 Self::Number(JsonNumber::F64(value))
703 }
704}
705
706impl<T> From<Option<T>> for JsonValue
707where
708 T: Into<JsonValue>,
709{
710 fn from(value: Option<T>) -> Self {
711 match value {
712 Some(value) => value.into(),
713 None => Self::Null,
714 }
715 }
716}
717
718impl<T> From<Vec<T>> for JsonValue
719where
720 T: Into<JsonValue>,
721{
722 fn from(values: Vec<T>) -> Self {
723 Self::Array(values.into_iter().map(Into::into).collect())
724 }
725}
726
727
728impl<K, V> std::iter::FromIterator<(K, V)> for JsonValue
729where
730 K: Into<String>,
731 V: Into<JsonValue>,
732{
733 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
734 Self::Object(
735 iter.into_iter()
736 .map(|(key, value)| (key.into(), value.into()))
737 .collect(),
738 )
739 }
740}
741
742impl<T> std::iter::FromIterator<T> for JsonValue
743where
744 T: Into<JsonValue>,
745{
746 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
747 Self::Array(iter.into_iter().map(Into::into).collect())
748 }
749}
750
751pub fn escape_json_string(input: &str) -> String {
752 let mut out = Vec::with_capacity(input.len() + 2);
753 write_escaped_json_string(&mut out, input);
754 unsafe { String::from_utf8_unchecked(out) }
755}
756
757pub fn parse_json(input: &str) -> Result<JsonValue, JsonParseError> {
758 let mut parser = Parser::new(input);
759 let value = parser.parse_value()?;
760 parser.skip_whitespace();
761 if parser.is_eof() {
762 Ok(value)
763 } else {
764 Err(JsonParseError::UnexpectedTrailingCharacters(parser.index))
765 }
766}
767
768pub fn parse_json_borrowed(input: &str) -> Result<BorrowedJsonValue<'_>, JsonParseError> {
769 let mut parser = Parser::new(input);
770 let value = parser.parse_value_borrowed()?;
771 parser.skip_whitespace();
772 if parser.is_eof() {
773 Ok(value)
774 } else {
775 Err(JsonParseError::UnexpectedTrailingCharacters(parser.index))
776 }
777}
778
779pub fn parse_json_tape(input: &str) -> Result<JsonTape, JsonParseError> {
780 let mut parser = Parser::new(input);
781 let mut tokens = Vec::new();
782 parser.parse_tape_value(&mut tokens, None)?;
783 parser.skip_whitespace();
784 if parser.is_eof() {
785 Ok(JsonTape { tokens })
786 } else {
787 Err(JsonParseError::UnexpectedTrailingCharacters(parser.index))
788 }
789}
790
791
792pub fn from_str(input: &str) -> Result<JsonValue, JsonParseError> {
793 parse_json(input)
794}
795
796pub fn from_slice(input: &[u8]) -> Result<JsonValue, JsonParseError> {
797 let input = std::str::from_utf8(input).map_err(|_| JsonParseError::InvalidUtf8)?;
798 parse_json(input)
799}
800
801pub fn to_string(value: &JsonValue) -> Result<String, JsonError> {
802 value.to_json_string()
803}
804
805pub fn to_vec(value: &JsonValue) -> Result<Vec<u8>, JsonError> {
806 let mut out = Vec::with_capacity(initial_json_capacity(value));
807 write_json_value(&mut out, value)?;
808 Ok(out)
809}
810
811pub fn from_reader<R: Read>(mut reader: R) -> Result<JsonValue, JsonParseError> {
812 let mut input = String::new();
813 reader
814 .read_to_string(&mut input)
815 .map_err(|_| JsonParseError::InvalidUtf8)?;
816 parse_json(&input)
817}
818
819pub fn to_writer<W: Write>(mut writer: W, value: &JsonValue) -> Result<(), JsonError> {
820 let bytes = to_vec(value)?;
821 writer.write_all(&bytes).map_err(|_| JsonError::Io)
822}
823
824pub fn to_string_pretty(value: &JsonValue) -> Result<String, JsonError> {
825 let mut out = Vec::with_capacity(initial_json_capacity(value) + 16);
826 write_json_value_pretty(&mut out, value, 0)?;
827 Ok(unsafe { String::from_utf8_unchecked(out) })
828}
829
830pub fn to_vec_pretty(value: &JsonValue) -> Result<Vec<u8>, JsonError> {
831 let mut out = Vec::with_capacity(initial_json_capacity(value) + 16);
832 write_json_value_pretty(&mut out, value, 0)?;
833 Ok(out)
834}
835
836pub fn to_writer_pretty<W: Write>(mut writer: W, value: &JsonValue) -> Result<(), JsonError> {
837 let bytes = to_vec_pretty(value)?;
838 writer.write_all(&bytes).map_err(|_| JsonError::Io)
839}
840
841impl JsonTape {
842 pub fn root<'a>(&'a self, input: &'a str) -> Option<TapeValue<'a>> {
843 (!self.tokens.is_empty()).then_some(TapeValue {
844 tape: self,
845 input,
846 index: 0,
847 })
848 }
849}
850
851impl<'a> TapeValue<'a> {
852 pub fn kind(&self) -> TapeTokenKind {
853 self.tape.tokens[self.index].kind
854 }
855
856 pub fn as_str(&self) -> Option<&'a str> {
857 let token = &self.tape.tokens[self.index];
858 match token.kind {
859 TapeTokenKind::String | TapeTokenKind::Key => {
860 if self.input.as_bytes()[token.start] == b'"'
861 && self.input.as_bytes()[token.end - 1] == b'"'
862 {
863 Some(&self.input[token.start + 1..token.end - 1])
864 } else {
865 None
866 }
867 }
868 _ => None,
869 }
870 }
871
872 pub fn get(&self, key: &str) -> Option<TapeValue<'a>> {
873 if self.kind() != TapeTokenKind::Object {
874 return None;
875 }
876 self.get_linear(key)
877 }
878
879 pub fn build_object_index(&self) -> Option<TapeObjectIndex> {
880 if self.kind() != TapeTokenKind::Object {
881 return None;
882 }
883 let parent = self.index;
884 let tokens = &self.tape.tokens;
885 let mut entries = Vec::new();
886 let mut i = self.index + 1;
887 while i + 1 < tokens.len() {
888 if tokens[i].parent != Some(parent) {
889 i += 1;
890 continue;
891 }
892 if tokens[i].kind == TapeTokenKind::Key && tokens[i + 1].parent == Some(parent) {
893 let candidate = TapeValue {
894 tape: self.tape,
895 input: self.input,
896 index: i,
897 };
898 let key = candidate.as_str().unwrap_or("");
899 let hash = hash_key(key.as_bytes());
900 entries.push((hash, i, i + 1));
901 i += 2;
902 } else {
903 i += 1;
904 }
905 }
906 let bucket_count = (entries.len().next_power_of_two().max(1)) * 2;
907 let mut buckets = vec![Vec::new(); bucket_count];
908 for entry in entries {
909 let bucket = (entry.0 as usize) & (bucket_count - 1);
910 buckets[bucket].push(entry);
911 }
912 Some(TapeObjectIndex { buckets })
913 }
914
915 pub fn with_index<'b>(&'b self, index: &'b TapeObjectIndex) -> IndexedTapeObject<'b> {
916 IndexedTapeObject {
917 object: TapeValue {
918 tape: self.tape,
919 input: self.input,
920 index: self.index,
921 },
922 index,
923 }
924 }
925
926 fn get_linear(&self, key: &str) -> Option<TapeValue<'a>> {
927 let parent = self.index;
928 let tokens = &self.tape.tokens;
929 let mut i = self.index + 1;
930 while i < tokens.len() {
931 if tokens[i].parent != Some(parent) {
932 i += 1;
933 continue;
934 }
935 if tokens[i].kind != TapeTokenKind::Key {
936 i += 1;
937 continue;
938 }
939 let candidate = TapeValue {
940 tape: self.tape,
941 input: self.input,
942 index: i,
943 };
944 if candidate.as_str() == Some(key) {
945 let value_index = i + 1;
946 if value_index < tokens.len() && tokens[value_index].parent == Some(parent) {
947 return Some(TapeValue {
948 tape: self.tape,
949 input: self.input,
950 index: value_index,
951 });
952 }
953 return None;
954 }
955 i += 1;
956 }
957 None
958 }
959}
960
961impl TapeObjectIndex {
962 pub fn get<'a>(&self, object: TapeValue<'a>, key: &str) -> Option<TapeValue<'a>> {
963 self.get_hashed(object, hash_key(key.as_bytes()), key)
964 }
965
966 pub fn get_compiled<'a>(&self, object: TapeValue<'a>, key: &CompiledTapeKey) -> Option<TapeValue<'a>> {
967 self.get_hashed(object, key.hash, &key.key)
968 }
969
970 fn get_hashed<'a>(&self, object: TapeValue<'a>, hash: u64, key: &str) -> Option<TapeValue<'a>> {
971 let bucket = (hash as usize) & (self.buckets.len() - 1);
972 for (entry_hash, key_index, value_index) in &self.buckets[bucket] {
973 if *entry_hash != hash {
974 continue;
975 }
976 let candidate = TapeValue {
977 tape: object.tape,
978 input: object.input,
979 index: *key_index,
980 };
981 if candidate.as_str() == Some(key) {
982 return Some(TapeValue {
983 tape: object.tape,
984 input: object.input,
985 index: *value_index,
986 });
987 }
988 }
989 None
990 }
991}
992
993impl CompiledTapeKey {
994 pub fn new(key: impl Into<String>) -> Self {
995 let key = key.into();
996 let hash = hash_key(key.as_bytes());
997 Self { key, hash }
998 }
999
1000 pub fn as_str(&self) -> &str {
1001 &self.key
1002 }
1003}
1004
1005impl CompiledTapeKeys {
1006 pub fn new(keys: &[&str]) -> Self {
1007 Self {
1008 keys: keys.iter().map(|key| CompiledTapeKey::new(*key)).collect(),
1009 }
1010 }
1011
1012 pub fn iter(&self) -> impl Iterator<Item = &CompiledTapeKey> {
1013 self.keys.iter()
1014 }
1015}
1016
1017impl<'a> IndexedTapeObject<'a> {
1018 pub fn get(&self, key: &str) -> Option<TapeValue<'a>> {
1019 self.index.get(self.object, key)
1020 }
1021
1022 pub fn get_compiled(&self, key: &CompiledTapeKey) -> Option<TapeValue<'a>> {
1023 self.index.get_compiled(self.object, key)
1024 }
1025
1026 pub fn get_many<'b>(
1027 &'b self,
1028 keys: &'b [&'b str],
1029 ) -> impl Iterator<Item = Option<TapeValue<'a>>> + 'b {
1030 keys.iter().map(|key| self.get(key))
1031 }
1032
1033 pub fn get_compiled_many<'b>(
1034 &'b self,
1035 keys: &'b CompiledTapeKeys,
1036 ) -> impl Iterator<Item = Option<TapeValue<'a>>> + 'b {
1037 keys.iter().map(|key| self.get_compiled(key))
1038 }
1039}
1040
1041
1042impl fmt::Display for JsonValue {
1043 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1044 match self.to_json_string() {
1045 Ok(json) => f.write_str(&json),
1046 Err(_) => Err(fmt::Error),
1047 }
1048 }
1049}
1050
1051static JSON_NULL: JsonValue = JsonValue::Null;
1052
1053pub trait ValueIndex {
1054 fn index_into<'a>(&self, value: &'a JsonValue) -> Option<&'a JsonValue>;
1055 fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> Option<&'a mut JsonValue>;
1056}
1057
1058impl ValueIndex for usize {
1059 fn index_into<'a>(&self, value: &'a JsonValue) -> Option<&'a JsonValue> {
1060 match value {
1061 JsonValue::Array(values) => values.get(*self),
1062 _ => None,
1063 }
1064 }
1065
1066 fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> Option<&'a mut JsonValue> {
1067 match value {
1068 JsonValue::Array(values) => values.get_mut(*self),
1069 _ => None,
1070 }
1071 }
1072}
1073
1074impl ValueIndex for str {
1075 fn index_into<'a>(&self, value: &'a JsonValue) -> Option<&'a JsonValue> {
1076 match value {
1077 JsonValue::Object(entries) => object_get(entries, self),
1078 _ => None,
1079 }
1080 }
1081
1082 fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> Option<&'a mut JsonValue> {
1083 match value {
1084 JsonValue::Object(entries) => object_get_mut(entries, self),
1085 _ => None,
1086 }
1087 }
1088}
1089
1090impl ValueIndex for String {
1091 fn index_into<'a>(&self, value: &'a JsonValue) -> Option<&'a JsonValue> {
1092 self.as_str().index_into(value)
1093 }
1094
1095 fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> Option<&'a mut JsonValue> {
1096 self.as_str().index_into_mut(value)
1097 }
1098}
1099
1100impl<T> ValueIndex for &T
1101where
1102 T: ?Sized + ValueIndex,
1103{
1104 fn index_into<'a>(&self, value: &'a JsonValue) -> Option<&'a JsonValue> {
1105 (**self).index_into(value)
1106 }
1107
1108 fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> Option<&'a mut JsonValue> {
1109 (**self).index_into_mut(value)
1110 }
1111}
1112
1113fn object_get<'a>(entries: &'a [(String, JsonValue)], key: &str) -> Option<&'a JsonValue> {
1114 entries
1115 .iter()
1116 .find(|(candidate, _)| candidate == key)
1117 .map(|(_, value)| value)
1118}
1119
1120fn object_get_mut<'a>(entries: &'a mut Vec<(String, JsonValue)>, key: &str) -> Option<&'a mut JsonValue> {
1121 entries
1122 .iter_mut()
1123 .find(|(candidate, _)| candidate == key)
1124 .map(|(_, value)| value)
1125}
1126
1127fn object_index_or_insert<'a>(value: &'a mut JsonValue, key: &str) -> &'a mut JsonValue {
1128 if matches!(value, JsonValue::Null) {
1129 *value = JsonValue::Object(Vec::new());
1130 }
1131 match value {
1132 JsonValue::Object(entries) => {
1133 if let Some(pos) = entries.iter().position(|(candidate, _)| candidate == key) {
1134 &mut entries[pos].1
1135 } else {
1136 entries.push((key.to_owned(), JsonValue::Null));
1137 &mut entries.last_mut().unwrap().1
1138 }
1139 }
1140 JsonValue::Null => unreachable!(),
1141 JsonValue::Bool(_) => panic!("cannot access key {:?} in JSON boolean", key),
1142 JsonValue::Number(_) => panic!("cannot access key {:?} in JSON number", key),
1143 JsonValue::String(_) => panic!("cannot access key {:?} in JSON string", key),
1144 JsonValue::Array(_) => panic!("cannot access key {:?} in JSON array", key),
1145 }
1146}
1147
1148fn array_index_or_panic(value: &mut JsonValue, index: usize) -> &mut JsonValue {
1149 match value {
1150 JsonValue::Array(values) => {
1151 let len = values.len();
1152 values.get_mut(index).unwrap_or_else(|| panic!("cannot access index {} of JSON array of length {}", index, len))
1153 }
1154 JsonValue::Null => panic!("cannot access index {} of JSON null", index),
1155 JsonValue::Bool(_) => panic!("cannot access index {} of JSON boolean", index),
1156 JsonValue::Number(_) => panic!("cannot access index {} of JSON number", index),
1157 JsonValue::String(_) => panic!("cannot access index {} of JSON string", index),
1158 JsonValue::Object(_) => panic!("cannot access index {} of JSON object", index),
1159 }
1160}
1161
1162impl Index<&str> for JsonValue {
1163 type Output = JsonValue;
1164
1165 fn index(&self, index: &str) -> &Self::Output {
1166 match self {
1167 JsonValue::Object(entries) => object_get(entries, index).unwrap_or(&JSON_NULL),
1168 _ => &JSON_NULL,
1169 }
1170 }
1171}
1172
1173impl Index<String> for JsonValue {
1174 type Output = JsonValue;
1175
1176 fn index(&self, index: String) -> &Self::Output {
1177 self.index(index.as_str())
1178 }
1179}
1180
1181impl Index<usize> for JsonValue {
1182 type Output = JsonValue;
1183
1184 fn index(&self, index: usize) -> &Self::Output {
1185 match self {
1186 JsonValue::Array(values) => values.get(index).unwrap_or(&JSON_NULL),
1187 _ => &JSON_NULL,
1188 }
1189 }
1190}
1191
1192impl IndexMut<&str> for JsonValue {
1193 fn index_mut(&mut self, index: &str) -> &mut Self::Output {
1194 object_index_or_insert(self, index)
1195 }
1196}
1197
1198impl IndexMut<String> for JsonValue {
1199 fn index_mut(&mut self, index: String) -> &mut Self::Output {
1200 object_index_or_insert(self, &index)
1201 }
1202}
1203
1204impl IndexMut<usize> for JsonValue {
1205 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1206 array_index_or_panic(self, index)
1207 }
1208}
1209
1210fn eq_i64(value: &JsonValue, other: i64) -> bool {
1211 value.as_i64() == Some(other)
1212}
1213
1214fn eq_u64(value: &JsonValue, other: u64) -> bool {
1215 value.as_u64() == Some(other)
1216}
1217
1218fn eq_f32(value: &JsonValue, other: f32) -> bool {
1219 value.as_f32() == Some(other)
1220}
1221
1222fn eq_f64(value: &JsonValue, other: f64) -> bool {
1223 value.as_f64() == Some(other)
1224}
1225
1226fn eq_bool(value: &JsonValue, other: bool) -> bool {
1227 value.as_bool() == Some(other)
1228}
1229
1230fn eq_str(value: &JsonValue, other: &str) -> bool {
1231 value.as_str() == Some(other)
1232}
1233
1234impl PartialEq<str> for JsonValue {
1235 fn eq(&self, other: &str) -> bool {
1236 eq_str(self, other)
1237 }
1238}
1239
1240impl PartialEq<&str> for JsonValue {
1241 fn eq(&self, other: &&str) -> bool {
1242 eq_str(self, *other)
1243 }
1244}
1245
1246impl PartialEq<JsonValue> for str {
1247 fn eq(&self, other: &JsonValue) -> bool {
1248 eq_str(other, self)
1249 }
1250}
1251
1252impl PartialEq<JsonValue> for &str {
1253 fn eq(&self, other: &JsonValue) -> bool {
1254 eq_str(other, *self)
1255 }
1256}
1257
1258impl PartialEq<String> for JsonValue {
1259 fn eq(&self, other: &String) -> bool {
1260 eq_str(self, other.as_str())
1261 }
1262}
1263
1264impl PartialEq<JsonValue> for String {
1265 fn eq(&self, other: &JsonValue) -> bool {
1266 eq_str(other, self.as_str())
1267 }
1268}
1269
1270macro_rules! partialeq_numeric {
1271 ($($eq:ident [$($ty:ty)*])*) => {
1272 $($(
1273 impl PartialEq<$ty> for JsonValue {
1274 fn eq(&self, other: &$ty) -> bool {
1275 $eq(self, *other as _)
1276 }
1277 }
1278
1279 impl PartialEq<JsonValue> for $ty {
1280 fn eq(&self, other: &JsonValue) -> bool {
1281 $eq(other, *self as _)
1282 }
1283 }
1284
1285 impl<'a> PartialEq<$ty> for &'a JsonValue {
1286 fn eq(&self, other: &$ty) -> bool {
1287 $eq(*self, *other as _)
1288 }
1289 }
1290
1291 impl<'a> PartialEq<$ty> for &'a mut JsonValue {
1292 fn eq(&self, other: &$ty) -> bool {
1293 $eq(*self, *other as _)
1294 }
1295 }
1296 )*)*
1297 }
1298}
1299
1300partialeq_numeric! {
1301 eq_i64[i8 i16 i32 i64 isize]
1302 eq_u64[u8 u16 u32 u64 usize]
1303 eq_f32[f32]
1304 eq_f64[f64]
1305 eq_bool[bool]
1306}
1307
1308#[macro_export]
1309macro_rules! json_unexpected {
1310 ($unexpected:tt) => {
1311 compile_error!(concat!("unexpected token in json! macro: ", stringify!($unexpected)))
1312 };
1313 () => {
1314 compile_error!("unexpected end of json! macro invocation")
1315 };
1316}
1317
1318#[macro_export]
1319macro_rules! json {
1320 ($($json:tt)+) => {
1321 $crate::json_internal!($($json)+)
1322 };
1323}
1324
1325#[macro_export]
1326#[doc(hidden)]
1327macro_rules! json_internal {
1328 (@array [$($elems:expr,)*]) => {
1329 vec![$($elems,)*]
1330 };
1331 (@array [$($elems:expr),*]) => {
1332 vec![$($elems),*]
1333 };
1334 (@array [$($elems:expr,)*] null $($rest:tt)*) => {
1335 $crate::json_internal!(@array [$($elems,)* $crate::json_internal!(null)] $($rest)*)
1336 };
1337 (@array [$($elems:expr,)*] true $($rest:tt)*) => {
1338 $crate::json_internal!(@array [$($elems,)* $crate::json_internal!(true)] $($rest)*)
1339 };
1340 (@array [$($elems:expr,)*] false $($rest:tt)*) => {
1341 $crate::json_internal!(@array [$($elems,)* $crate::json_internal!(false)] $($rest)*)
1342 };
1343 (@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => {
1344 $crate::json_internal!(@array [$($elems,)* $crate::json_internal!([$($array)*])] $($rest)*)
1345 };
1346 (@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => {
1347 $crate::json_internal!(@array [$($elems,)* $crate::json_internal!({$($map)*})] $($rest)*)
1348 };
1349 (@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => {
1350 $crate::json_internal!(@array [$($elems,)* $crate::json_internal!($next),] $($rest)*)
1351 };
1352 (@array [$($elems:expr,)*] $last:expr) => {
1353 $crate::json_internal!(@array [$($elems,)* $crate::json_internal!($last)])
1354 };
1355 (@array [$($elems:expr),*] , $($rest:tt)*) => {
1356 $crate::json_internal!(@array [$($elems,)*] $($rest)*)
1357 };
1358 (@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => {
1359 $crate::json_unexpected!($unexpected)
1360 };
1361
1362 (@object $object:ident () () ()) => {};
1363 (@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => {
1364 $object.push((($($key)+).into(), $value));
1365 $crate::json_internal!(@object $object () ($($rest)*) ($($rest)*));
1366 };
1367 (@object $object:ident [$($key:tt)+] ($value:expr)) => {
1368 $object.push((($($key)+).into(), $value));
1369 };
1370 (@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => {
1371 $crate::json_unexpected!($unexpected)
1372 };
1373 (@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => {
1374 $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!(null)) $($rest)*);
1375 };
1376 (@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => {
1377 $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!(true)) $($rest)*);
1378 };
1379 (@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => {
1380 $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!(false)) $($rest)*);
1381 };
1382 (@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => {
1383 $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!([$($array)*])) $($rest)*);
1384 };
1385 (@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => {
1386 $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!({$($map)*})) $($rest)*);
1387 };
1388 (@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => {
1389 $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!($value)) , $($rest)*);
1390 };
1391 (@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => {
1392 $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!($value)));
1393 };
1394 (@object $object:ident ($($key:tt)+) (:) $copy:tt) => {
1395 $crate::json_internal!();
1396 };
1397 (@object $object:ident ($($key:tt)+) () $copy:tt) => {
1398 $crate::json_internal!();
1399 };
1400 (@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => {
1401 $crate::json_unexpected!($colon)
1402 };
1403 (@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => {
1404 $crate::json_unexpected!($comma)
1405 };
1406 (@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) ($($copy:tt)*)) => {
1407 $crate::json_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*));
1408 };
1409
1410 (null) => { $crate::JsonValue::Null };
1411 (true) => { $crate::JsonValue::Bool(true) };
1412 (false) => { $crate::JsonValue::Bool(false) };
1413 ([]) => { $crate::JsonValue::Array(vec![]) };
1414 ([ $($tt:tt)+ ]) => { $crate::JsonValue::Array($crate::json_internal!(@array [] $($tt)+)) };
1415 ({}) => { $crate::JsonValue::Object(vec![]) };
1416 ({ $($tt:tt)+ }) => {{
1417 let mut object = Vec::new();
1418 $crate::json_internal!(@object object () ($($tt)+) ($($tt)+));
1419 $crate::JsonValue::Object(object)
1420 }};
1421 ($other:expr) => { $crate::JsonValue::from($other) };
1422}
1423
1424fn decode_pointer_segment(segment: &str) -> String {
1425 let mut out = String::with_capacity(segment.len());
1426 let bytes = segment.as_bytes();
1427 let mut i = 0;
1428 while i < bytes.len() {
1429 if bytes[i] == b'~' && i + 1 < bytes.len() {
1430 match bytes[i + 1] {
1431 b'0' => {
1432 out.push('~');
1433 i += 2;
1434 continue;
1435 }
1436 b'1' => {
1437 out.push('/');
1438 i += 2;
1439 continue;
1440 }
1441 _ => {}
1442 }
1443 }
1444 out.push(bytes[i] as char);
1445 i += 1;
1446 }
1447 out
1448}
1449
1450fn write_indent(out: &mut Vec<u8>, depth: usize) {
1451 for _ in 0..depth {
1452 out.extend_from_slice(b" ");
1453 }
1454}
1455
1456fn write_json_value_pretty(out: &mut Vec<u8>, value: &JsonValue, depth: usize) -> Result<(), JsonError> {
1457 match value {
1458 JsonValue::Null | JsonValue::Bool(_) | JsonValue::Number(_) | JsonValue::String(_) => {
1459 write_json_value(out, value)
1460 }
1461 JsonValue::Array(values) => {
1462 out.push(b'[');
1463 if !values.is_empty() {
1464 out.push(b'\n');
1465 for (index, value) in values.iter().enumerate() {
1466 if index > 0 {
1467 out.extend_from_slice(b",\n");
1468 }
1469 write_indent(out, depth + 1);
1470 write_json_value_pretty(out, value, depth + 1)?;
1471 }
1472 out.push(b'\n');
1473 write_indent(out, depth);
1474 }
1475 out.push(b']');
1476 Ok(())
1477 }
1478 JsonValue::Object(entries) => {
1479 out.push(b'{');
1480 if !entries.is_empty() {
1481 out.push(b'\n');
1482 for (index, (key, value)) in entries.iter().enumerate() {
1483 if index > 0 {
1484 out.extend_from_slice(b",\n");
1485 }
1486 write_indent(out, depth + 1);
1487 write_json_key(out, key);
1488 out.push(b' ');
1489 write_json_value_pretty(out, value, depth + 1)?;
1490 }
1491 out.push(b'\n');
1492 write_indent(out, depth);
1493 }
1494 out.push(b'}');
1495 Ok(())
1496 }
1497 }
1498}
1499
1500fn hash_key(bytes: &[u8]) -> u64 {
1501 let mut hash = 1469598103934665603u64;
1502 for &byte in bytes {
1503 hash ^= byte as u64;
1504 hash = hash.wrapping_mul(1099511628211u64);
1505 }
1506 hash
1507}
1508
1509#[inline]
1510fn write_json_value(out: &mut Vec<u8>, value: &JsonValue) -> Result<(), JsonError> {
1511 match value {
1512 JsonValue::Null => out.extend_from_slice(b"null"),
1513 JsonValue::Bool(value) => {
1514 if *value {
1515 out.extend_from_slice(b"true");
1516 } else {
1517 out.extend_from_slice(b"false");
1518 }
1519 }
1520 JsonValue::Number(number) => write_json_number(out, number)?,
1521 JsonValue::String(value) => {
1522 write_escaped_json_string(out, value);
1523 }
1524 JsonValue::Array(values) => {
1525 write_json_array(out, values)?;
1526 }
1527 JsonValue::Object(entries) => {
1528 write_json_object(out, entries)?;
1529 }
1530 }
1531 Ok(())
1532}
1533
1534#[inline]
1535fn write_json_number(out: &mut Vec<u8>, value: &JsonNumber) -> Result<(), JsonError> {
1536 match value {
1537 JsonNumber::I64(value) => {
1538 append_i64(out, *value);
1539 Ok(())
1540 }
1541 JsonNumber::U64(value) => {
1542 append_u64(out, *value);
1543 Ok(())
1544 }
1545 JsonNumber::F64(value) => {
1546 if !value.is_finite() {
1547 return Err(JsonError::NonFiniteNumber);
1548 }
1549 out.extend_from_slice(value.to_string().as_bytes());
1550 Ok(())
1551 }
1552 }
1553}
1554
1555#[inline]
1556fn write_escaped_json_string(out: &mut Vec<u8>, input: &str) {
1557 out.push(b'"');
1558 let bytes = input.as_bytes();
1559 let mut fast_index = 0usize;
1560 while fast_index < bytes.len() {
1561 let byte = bytes[fast_index];
1562 if needs_escape(byte) {
1563 break;
1564 }
1565 fast_index += 1;
1566 }
1567 if fast_index == bytes.len() {
1568 out.extend_from_slice(bytes);
1569 out.push(b'"');
1570 return;
1571 }
1572
1573 if fast_index > 0 {
1574 out.extend_from_slice(&bytes[..fast_index]);
1575 }
1576
1577 let mut chunk_start = fast_index;
1578 for (index, byte) in bytes.iter().copied().enumerate().skip(fast_index) {
1579 let escape = match byte {
1580 b'"' => Some(br#"\""#.as_slice()),
1581 b'\\' => Some(br#"\\"#.as_slice()),
1582 0x08 => Some(br#"\b"#.as_slice()),
1583 0x0c => Some(br#"\f"#.as_slice()),
1584 b'\n' => Some(br#"\n"#.as_slice()),
1585 b'\r' => Some(br#"\r"#.as_slice()),
1586 b'\t' => Some(br#"\t"#.as_slice()),
1587 _ => None,
1588 };
1589 if let Some(escape) = escape {
1590 if chunk_start < index {
1591 out.extend_from_slice(&bytes[chunk_start..index]);
1592 }
1593 out.extend_from_slice(escape);
1594 chunk_start = index + 1;
1595 continue;
1596 }
1597 if byte <= 0x1f {
1598 if chunk_start < index {
1599 out.extend_from_slice(&bytes[chunk_start..index]);
1600 }
1601 out.extend_from_slice(br#"\u00"#);
1602 out.push(hex_digit((byte >> 4) & 0x0f));
1603 out.push(hex_digit(byte & 0x0f));
1604 chunk_start = index + 1;
1605 }
1606 }
1607 if chunk_start < input.len() {
1608 out.extend_from_slice(&bytes[chunk_start..]);
1609 }
1610 out.push(b'"');
1611}
1612
1613#[inline]
1614fn needs_escape(byte: u8) -> bool {
1615 matches!(byte, b'"' | b'\\' | 0x00..=0x1f)
1616}
1617
1618#[inline]
1619fn write_json_array(out: &mut Vec<u8>, values: &[JsonValue]) -> Result<(), JsonError> {
1620 out.push(b'[');
1621 match values {
1622 [] => {}
1623 [one] => {
1624 write_json_value(out, one)?;
1625 }
1626 [a, b] => {
1627 write_json_value(out, a)?;
1628 out.push(b',');
1629 write_json_value(out, b)?;
1630 }
1631 [a, b, c] => {
1632 write_json_value(out, a)?;
1633 out.push(b',');
1634 write_json_value(out, b)?;
1635 out.push(b',');
1636 write_json_value(out, c)?;
1637 }
1638 _ => {
1639 let mut iter = values.iter();
1640 if let Some(first) = iter.next() {
1641 write_json_value(out, first)?;
1642 for value in iter {
1643 out.push(b',');
1644 write_json_value(out, value)?;
1645 }
1646 }
1647 }
1648 }
1649 out.push(b']');
1650 Ok(())
1651}
1652
1653#[inline]
1654fn write_json_object(out: &mut Vec<u8>, entries: &[(String, JsonValue)]) -> Result<(), JsonError> {
1655 out.push(b'{');
1656 match entries {
1657 [] => {}
1658 [(k1, v1)] => {
1659 write_json_key(out, k1);
1660 write_json_value(out, v1)?;
1661 }
1662 [(k1, v1), (k2, v2)] => {
1663 write_json_key(out, k1);
1664 write_json_value(out, v1)?;
1665 out.push(b',');
1666 write_json_key(out, k2);
1667 write_json_value(out, v2)?;
1668 }
1669 [(k1, v1), (k2, v2), (k3, v3)] => {
1670 write_json_key(out, k1);
1671 write_json_value(out, v1)?;
1672 out.push(b',');
1673 write_json_key(out, k2);
1674 write_json_value(out, v2)?;
1675 out.push(b',');
1676 write_json_key(out, k3);
1677 write_json_value(out, v3)?;
1678 }
1679 _ => {
1680 let mut iter = entries.iter();
1681 if let Some((first_key, first_value)) = iter.next() {
1682 write_json_key(out, first_key);
1683 write_json_value(out, first_value)?;
1684 for (key, value) in iter {
1685 out.push(b',');
1686 write_json_key(out, key);
1687 write_json_value(out, value)?;
1688 }
1689 }
1690 }
1691 }
1692 out.push(b'}');
1693 Ok(())
1694}
1695
1696#[inline]
1697fn write_json_key(out: &mut Vec<u8>, key: &str) {
1698 let bytes = key.as_bytes();
1699 if is_plain_json_string(bytes) {
1700 out.push(b'"');
1701 out.extend_from_slice(bytes);
1702 out.extend_from_slice(b"\":");
1703 } else {
1704 write_escaped_json_string(out, key);
1705 out.push(b':');
1706 }
1707}
1708
1709#[inline]
1710fn is_plain_json_string(bytes: &[u8]) -> bool {
1711 for &byte in bytes {
1712 if needs_escape(byte) {
1713 return false;
1714 }
1715 }
1716 true
1717}
1718
1719fn initial_json_capacity(value: &JsonValue) -> usize {
1720 match value {
1721 JsonValue::Null => 4,
1722 JsonValue::Bool(true) => 4,
1723 JsonValue::Bool(false) => 5,
1724 JsonValue::Number(JsonNumber::I64(value)) => estimate_i64_len(*value),
1725 JsonValue::Number(JsonNumber::U64(value)) => estimate_u64_len(*value),
1726 JsonValue::Number(JsonNumber::F64(_)) => 24,
1727 JsonValue::String(value) => estimate_escaped_string_len(value),
1728 JsonValue::Array(values) => 2 + values.len().saturating_mul(16),
1729 JsonValue::Object(entries) => {
1730 2 + entries
1731 .iter()
1732 .map(|(key, _)| estimate_escaped_string_len(key) + 8)
1733 .sum::<usize>()
1734 }
1735 }
1736}
1737
1738fn estimate_escaped_string_len(value: &str) -> usize {
1739 let mut len = 2;
1740 for ch in value.chars() {
1741 len += match ch {
1742 '"' | '\\' | '\u{08}' | '\u{0C}' | '\n' | '\r' | '\t' => 2,
1743 ch if ch <= '\u{1F}' => 6,
1744 ch => ch.len_utf8(),
1745 };
1746 }
1747 len
1748}
1749
1750fn estimate_u64_len(mut value: u64) -> usize {
1751 let mut len = 1;
1752 while value >= 10 {
1753 value /= 10;
1754 len += 1;
1755 }
1756 len
1757}
1758
1759fn estimate_i64_len(value: i64) -> usize {
1760 if value < 0 {
1761 1 + estimate_u64_len(value.unsigned_abs())
1762 } else {
1763 estimate_u64_len(value as u64)
1764 }
1765}
1766
1767fn append_i64(out: &mut Vec<u8>, value: i64) {
1768 if value < 0 {
1769 out.push(b'-');
1770 append_u64(out, value.unsigned_abs());
1771 } else {
1772 append_u64(out, value as u64);
1773 }
1774}
1775
1776fn append_u64(out: &mut Vec<u8>, mut value: u64) {
1777 let mut buf = [0u8; 20];
1778 let mut index = buf.len();
1779 loop {
1780 index -= 1;
1781 buf[index] = b'0' + (value % 10) as u8;
1782 value /= 10;
1783 if value == 0 {
1784 break;
1785 }
1786 }
1787 out.extend_from_slice(&buf[index..]);
1788}
1789
1790fn hex_digit(value: u8) -> u8 {
1791 match value {
1792 0..=9 => b'0' + value,
1793 10..=15 => b'a' + (value - 10),
1794 _ => unreachable!(),
1795 }
1796}
1797
1798struct Parser<'a> {
1799 input: &'a str,
1800 bytes: &'a [u8],
1801 index: usize,
1802}
1803
1804impl<'a> Parser<'a> {
1805 fn new(input: &'a str) -> Self {
1806 Self {
1807 input,
1808 bytes: input.as_bytes(),
1809 index: 0,
1810 }
1811 }
1812
1813 fn parse_value(&mut self) -> Result<JsonValue, JsonParseError> {
1814 self.skip_whitespace();
1815 match self.peek_byte() {
1816 Some(b'n') => self.parse_literal(b"null", JsonValue::Null),
1817 Some(b't') => self.parse_literal(b"true", JsonValue::Bool(true)),
1818 Some(b'f') => self.parse_literal(b"false", JsonValue::Bool(false)),
1819 Some(b'"') => Ok(JsonValue::String(self.parse_string()?)),
1820 Some(b'[') => self.parse_array(),
1821 Some(b'{') => self.parse_object(),
1822 Some(b'-' | b'0'..=b'9') => self.parse_number().map(JsonValue::Number),
1823 Some(found) => Err(JsonParseError::UnexpectedCharacter {
1824 index: self.index,
1825 found: found as char,
1826 }),
1827 None => Err(JsonParseError::UnexpectedEnd),
1828 }
1829 }
1830
1831 fn parse_value_borrowed(&mut self) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1832 self.skip_whitespace();
1833 match self.peek_byte() {
1834 Some(b'n') => self.parse_literal_borrowed(b"null", BorrowedJsonValue::Null),
1835 Some(b't') => self.parse_literal_borrowed(b"true", BorrowedJsonValue::Bool(true)),
1836 Some(b'f') => self.parse_literal_borrowed(b"false", BorrowedJsonValue::Bool(false)),
1837 Some(b'"') => Ok(BorrowedJsonValue::String(self.parse_string_borrowed()?)),
1838 Some(b'[') => self.parse_array_borrowed(),
1839 Some(b'{') => self.parse_object_borrowed(),
1840 Some(b'-' | b'0'..=b'9') => self.parse_number().map(BorrowedJsonValue::Number),
1841 Some(found) => Err(JsonParseError::UnexpectedCharacter {
1842 index: self.index,
1843 found: found as char,
1844 }),
1845 None => Err(JsonParseError::UnexpectedEnd),
1846 }
1847 }
1848
1849 fn parse_tape_value(
1850 &mut self,
1851 tokens: &mut Vec<TapeToken>,
1852 parent: Option<usize>,
1853 ) -> Result<usize, JsonParseError> {
1854 self.skip_whitespace();
1855 match self.peek_byte() {
1856 Some(b'n') => self.parse_tape_literal(tokens, parent, b"null", TapeTokenKind::Null),
1857 Some(b't') => self.parse_tape_literal(tokens, parent, b"true", TapeTokenKind::Bool),
1858 Some(b'f') => self.parse_tape_literal(tokens, parent, b"false", TapeTokenKind::Bool),
1859 Some(b'"') => self.parse_tape_string(tokens, parent, TapeTokenKind::String),
1860 Some(b'[') => self.parse_tape_array(tokens, parent),
1861 Some(b'{') => self.parse_tape_object(tokens, parent),
1862 Some(b'-' | b'0'..=b'9') => self.parse_tape_number(tokens, parent),
1863 Some(found) => Err(JsonParseError::UnexpectedCharacter {
1864 index: self.index,
1865 found: found as char,
1866 }),
1867 None => Err(JsonParseError::UnexpectedEnd),
1868 }
1869 }
1870
1871 fn parse_literal(
1872 &mut self,
1873 expected: &[u8],
1874 value: JsonValue,
1875 ) -> Result<JsonValue, JsonParseError> {
1876 if self.bytes[self.index..].starts_with(expected) {
1877 self.index += expected.len();
1878 Ok(value)
1879 } else {
1880 Err(JsonParseError::InvalidLiteral { index: self.index })
1881 }
1882 }
1883
1884 fn parse_literal_borrowed(
1885 &mut self,
1886 expected: &[u8],
1887 value: BorrowedJsonValue<'a>,
1888 ) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1889 if self.bytes[self.index..].starts_with(expected) {
1890 self.index += expected.len();
1891 Ok(value)
1892 } else {
1893 Err(JsonParseError::InvalidLiteral { index: self.index })
1894 }
1895 }
1896
1897 fn parse_tape_literal(
1898 &mut self,
1899 tokens: &mut Vec<TapeToken>,
1900 parent: Option<usize>,
1901 expected: &[u8],
1902 kind: TapeTokenKind,
1903 ) -> Result<usize, JsonParseError> {
1904 let start = self.index;
1905 if self.bytes[self.index..].starts_with(expected) {
1906 self.index += expected.len();
1907 let token_index = tokens.len();
1908 tokens.push(TapeToken {
1909 kind,
1910 start,
1911 end: self.index,
1912 parent,
1913 });
1914 Ok(token_index)
1915 } else {
1916 Err(JsonParseError::InvalidLiteral { index: self.index })
1917 }
1918 }
1919
1920 fn parse_array(&mut self) -> Result<JsonValue, JsonParseError> {
1921 self.consume_byte(b'[')?;
1922 self.skip_whitespace();
1923 let mut values = Vec::new();
1924 if self.try_consume_byte(b']') {
1925 return Ok(JsonValue::Array(values));
1926 }
1927 loop {
1928 values.push(self.parse_value()?);
1929 self.skip_whitespace();
1930 if self.try_consume_byte(b']') {
1931 break;
1932 }
1933 if !self.try_consume_byte(b',') {
1934 return Err(JsonParseError::ExpectedCommaOrEnd {
1935 index: self.index,
1936 context: "array",
1937 });
1938 }
1939 self.skip_whitespace();
1940 }
1941 Ok(JsonValue::Array(values))
1942 }
1943
1944 fn parse_array_borrowed(&mut self) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1945 self.consume_byte(b'[')?;
1946 self.skip_whitespace();
1947 let mut values = Vec::new();
1948 if self.try_consume_byte(b']') {
1949 return Ok(BorrowedJsonValue::Array(values));
1950 }
1951 loop {
1952 values.push(self.parse_value_borrowed()?);
1953 self.skip_whitespace();
1954 if self.try_consume_byte(b']') {
1955 break;
1956 }
1957 if !self.try_consume_byte(b',') {
1958 return Err(JsonParseError::ExpectedCommaOrEnd {
1959 index: self.index,
1960 context: "array",
1961 });
1962 }
1963 self.skip_whitespace();
1964 }
1965 Ok(BorrowedJsonValue::Array(values))
1966 }
1967
1968 fn parse_tape_array(
1969 &mut self,
1970 tokens: &mut Vec<TapeToken>,
1971 parent: Option<usize>,
1972 ) -> Result<usize, JsonParseError> {
1973 let start = self.index;
1974 self.consume_byte(b'[')?;
1975 let token_index = tokens.len();
1976 tokens.push(TapeToken {
1977 kind: TapeTokenKind::Array,
1978 start,
1979 end: start,
1980 parent,
1981 });
1982 self.skip_whitespace();
1983 if self.try_consume_byte(b']') {
1984 tokens[token_index].end = self.index;
1985 return Ok(token_index);
1986 }
1987 loop {
1988 self.parse_tape_value(tokens, Some(token_index))?;
1989 self.skip_whitespace();
1990 if self.try_consume_byte(b']') {
1991 tokens[token_index].end = self.index;
1992 break;
1993 }
1994 if !self.try_consume_byte(b',') {
1995 return Err(JsonParseError::ExpectedCommaOrEnd {
1996 index: self.index,
1997 context: "array",
1998 });
1999 }
2000 self.skip_whitespace();
2001 }
2002 Ok(token_index)
2003 }
2004
2005 fn parse_object(&mut self) -> Result<JsonValue, JsonParseError> {
2006 self.consume_byte(b'{')?;
2007 self.skip_whitespace();
2008 let mut entries = Vec::new();
2009 if self.try_consume_byte(b'}') {
2010 return Ok(JsonValue::Object(entries));
2011 }
2012 loop {
2013 if self.peek_byte() != Some(b'"') {
2014 return match self.peek_byte() {
2015 Some(found) => Err(JsonParseError::UnexpectedCharacter {
2016 index: self.index,
2017 found: found as char,
2018 }),
2019 None => Err(JsonParseError::UnexpectedEnd),
2020 };
2021 }
2022 let key = self.parse_string()?;
2023 self.skip_whitespace();
2024 if !self.try_consume_byte(b':') {
2025 return Err(JsonParseError::ExpectedColon { index: self.index });
2026 }
2027 let value = self.parse_value()?;
2028 entries.push((key, value));
2029 self.skip_whitespace();
2030 if self.try_consume_byte(b'}') {
2031 break;
2032 }
2033 if !self.try_consume_byte(b',') {
2034 return Err(JsonParseError::ExpectedCommaOrEnd {
2035 index: self.index,
2036 context: "object",
2037 });
2038 }
2039 self.skip_whitespace();
2040 }
2041 Ok(JsonValue::Object(entries))
2042 }
2043
2044 fn parse_object_borrowed(&mut self) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
2045 self.consume_byte(b'{')?;
2046 self.skip_whitespace();
2047 let mut entries = Vec::new();
2048 if self.try_consume_byte(b'}') {
2049 return Ok(BorrowedJsonValue::Object(entries));
2050 }
2051 loop {
2052 if self.peek_byte() != Some(b'"') {
2053 return match self.peek_byte() {
2054 Some(found) => Err(JsonParseError::UnexpectedCharacter {
2055 index: self.index,
2056 found: found as char,
2057 }),
2058 None => Err(JsonParseError::UnexpectedEnd),
2059 };
2060 }
2061 let key = self.parse_string_borrowed()?;
2062 self.skip_whitespace();
2063 if !self.try_consume_byte(b':') {
2064 return Err(JsonParseError::ExpectedColon { index: self.index });
2065 }
2066 let value = self.parse_value_borrowed()?;
2067 entries.push((key, value));
2068 self.skip_whitespace();
2069 if self.try_consume_byte(b'}') {
2070 break;
2071 }
2072 if !self.try_consume_byte(b',') {
2073 return Err(JsonParseError::ExpectedCommaOrEnd {
2074 index: self.index,
2075 context: "object",
2076 });
2077 }
2078 self.skip_whitespace();
2079 }
2080 Ok(BorrowedJsonValue::Object(entries))
2081 }
2082
2083 fn parse_tape_object(
2084 &mut self,
2085 tokens: &mut Vec<TapeToken>,
2086 parent: Option<usize>,
2087 ) -> Result<usize, JsonParseError> {
2088 let start = self.index;
2089 self.consume_byte(b'{')?;
2090 let token_index = tokens.len();
2091 tokens.push(TapeToken {
2092 kind: TapeTokenKind::Object,
2093 start,
2094 end: start,
2095 parent,
2096 });
2097 self.skip_whitespace();
2098 if self.try_consume_byte(b'}') {
2099 tokens[token_index].end = self.index;
2100 return Ok(token_index);
2101 }
2102 loop {
2103 if self.peek_byte() != Some(b'"') {
2104 return match self.peek_byte() {
2105 Some(found) => Err(JsonParseError::UnexpectedCharacter {
2106 index: self.index,
2107 found: found as char,
2108 }),
2109 None => Err(JsonParseError::UnexpectedEnd),
2110 };
2111 }
2112 self.parse_tape_string(tokens, Some(token_index), TapeTokenKind::Key)?;
2113 self.skip_whitespace();
2114 if !self.try_consume_byte(b':') {
2115 return Err(JsonParseError::ExpectedColon { index: self.index });
2116 }
2117 self.parse_tape_value(tokens, Some(token_index))?;
2118 self.skip_whitespace();
2119 if self.try_consume_byte(b'}') {
2120 tokens[token_index].end = self.index;
2121 break;
2122 }
2123 if !self.try_consume_byte(b',') {
2124 return Err(JsonParseError::ExpectedCommaOrEnd {
2125 index: self.index,
2126 context: "object",
2127 });
2128 }
2129 self.skip_whitespace();
2130 }
2131 Ok(token_index)
2132 }
2133
2134 fn parse_string(&mut self) -> Result<String, JsonParseError> {
2135 self.consume_byte(b'"')?;
2136 let start = self.index;
2137 loop {
2138 let Some(byte) = self.next_byte() else {
2139 return Err(JsonParseError::UnexpectedEnd);
2140 };
2141 match byte {
2142 b'"' => {
2143 let slice = &self.input[start..self.index - 1];
2144 return Ok(slice.to_owned());
2145 }
2146 b'\\' => {
2147 let mut out = String::with_capacity(self.index - start + 8);
2148 out.push_str(&self.input[start..self.index - 1]);
2149 self.parse_escape_into(&mut out, self.index - 1)?;
2150 return self.parse_string_slow(out);
2151 }
2152 0x00..=0x1f => {
2153 return Err(JsonParseError::UnexpectedCharacter {
2154 index: self.index - 1,
2155 found: byte as char,
2156 })
2157 }
2158 _ => {}
2159 }
2160 }
2161 }
2162
2163 fn parse_string_borrowed(&mut self) -> Result<Cow<'a, str>, JsonParseError> {
2164 self.consume_byte(b'"')?;
2165 let start = self.index;
2166 loop {
2167 let Some(byte) = self.next_byte() else {
2168 return Err(JsonParseError::UnexpectedEnd);
2169 };
2170 match byte {
2171 b'"' => {
2172 let slice = &self.input[start..self.index - 1];
2173 return Ok(Cow::Borrowed(slice));
2174 }
2175 b'\\' => {
2176 let mut out = String::with_capacity(self.index - start + 8);
2177 out.push_str(&self.input[start..self.index - 1]);
2178 self.parse_escape_into(&mut out, self.index - 1)?;
2179 return self.parse_string_slow_borrowed(out);
2180 }
2181 0x00..=0x1f => {
2182 return Err(JsonParseError::UnexpectedCharacter {
2183 index: self.index - 1,
2184 found: byte as char,
2185 })
2186 }
2187 _ => {}
2188 }
2189 }
2190 }
2191
2192 fn parse_tape_string(
2193 &mut self,
2194 tokens: &mut Vec<TapeToken>,
2195 parent: Option<usize>,
2196 kind: TapeTokenKind,
2197 ) -> Result<usize, JsonParseError> {
2198 let start = self.index;
2199 self.skip_string_bytes()?;
2200 let token_index = tokens.len();
2201 tokens.push(TapeToken {
2202 kind,
2203 start,
2204 end: self.index,
2205 parent,
2206 });
2207 Ok(token_index)
2208 }
2209
2210 fn skip_string_bytes(&mut self) -> Result<(), JsonParseError> {
2211 self.consume_byte(b'"')?;
2212 loop {
2213 let Some(byte) = self.next_byte() else {
2214 return Err(JsonParseError::UnexpectedEnd);
2215 };
2216 match byte {
2217 b'"' => return Ok(()),
2218 b'\\' => {
2219 let escape_index = self.index - 1;
2220 let escaped = self.next_byte().ok_or(JsonParseError::UnexpectedEnd)?;
2221 match escaped {
2222 b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {}
2223 b'u' => {
2224 let scalar = self.parse_hex_quad(escape_index)?;
2225 if (0xD800..=0xDBFF).contains(&scalar) {
2226 if self.next_byte() != Some(b'\\') || self.next_byte() != Some(b'u')
2227 {
2228 return Err(JsonParseError::InvalidUnicodeScalar {
2229 index: escape_index,
2230 });
2231 }
2232 let low = self.parse_hex_quad(escape_index)?;
2233 if !(0xDC00..=0xDFFF).contains(&low) {
2234 return Err(JsonParseError::InvalidUnicodeScalar {
2235 index: escape_index,
2236 });
2237 }
2238 } else if (0xDC00..=0xDFFF).contains(&scalar) {
2239 return Err(JsonParseError::InvalidUnicodeScalar {
2240 index: escape_index,
2241 });
2242 }
2243 }
2244 _ => {
2245 return Err(JsonParseError::InvalidEscape {
2246 index: escape_index,
2247 })
2248 }
2249 }
2250 }
2251 0x00..=0x1f => {
2252 return Err(JsonParseError::UnexpectedCharacter {
2253 index: self.index - 1,
2254 found: byte as char,
2255 })
2256 }
2257 _ => {}
2258 }
2259 }
2260 }
2261
2262 fn parse_string_slow(&mut self, mut out: String) -> Result<String, JsonParseError> {
2263 let mut chunk_start = self.index;
2264 loop {
2265 let Some(byte) = self.next_byte() else {
2266 return Err(JsonParseError::UnexpectedEnd);
2267 };
2268 match byte {
2269 b'"' => {
2270 if chunk_start < self.index - 1 {
2271 out.push_str(&self.input[chunk_start..self.index - 1]);
2272 }
2273 return Ok(out);
2274 }
2275 b'\\' => {
2276 if chunk_start < self.index - 1 {
2277 out.push_str(&self.input[chunk_start..self.index - 1]);
2278 }
2279 self.parse_escape_into(&mut out, self.index - 1)?;
2280 chunk_start = self.index;
2281 }
2282 0x00..=0x1f => {
2283 return Err(JsonParseError::UnexpectedCharacter {
2284 index: self.index - 1,
2285 found: byte as char,
2286 })
2287 }
2288 _ => {}
2289 }
2290 }
2291 }
2292
2293 fn parse_string_slow_borrowed(
2294 &mut self,
2295 mut out: String,
2296 ) -> Result<Cow<'a, str>, JsonParseError> {
2297 let mut chunk_start = self.index;
2298 loop {
2299 let Some(byte) = self.next_byte() else {
2300 return Err(JsonParseError::UnexpectedEnd);
2301 };
2302 match byte {
2303 b'"' => {
2304 if chunk_start < self.index - 1 {
2305 out.push_str(&self.input[chunk_start..self.index - 1]);
2306 }
2307 return Ok(Cow::Owned(out));
2308 }
2309 b'\\' => {
2310 if chunk_start < self.index - 1 {
2311 out.push_str(&self.input[chunk_start..self.index - 1]);
2312 }
2313 self.parse_escape_into(&mut out, self.index - 1)?;
2314 chunk_start = self.index;
2315 }
2316 0x00..=0x1f => {
2317 return Err(JsonParseError::UnexpectedCharacter {
2318 index: self.index - 1,
2319 found: byte as char,
2320 })
2321 }
2322 _ => {}
2323 }
2324 }
2325 }
2326
2327 fn parse_escape_into(
2328 &mut self,
2329 out: &mut String,
2330 escape_index: usize,
2331 ) -> Result<(), JsonParseError> {
2332 let escaped = self.next_byte().ok_or(JsonParseError::UnexpectedEnd)?;
2333 match escaped {
2334 b'"' => out.push('"'),
2335 b'\\' => out.push('\\'),
2336 b'/' => out.push('/'),
2337 b'b' => out.push('\u{0008}'),
2338 b'f' => out.push('\u{000C}'),
2339 b'n' => out.push('\n'),
2340 b'r' => out.push('\r'),
2341 b't' => out.push('\t'),
2342 b'u' => out.push(self.parse_unicode_escape(escape_index)?),
2343 _ => {
2344 return Err(JsonParseError::InvalidEscape {
2345 index: escape_index,
2346 })
2347 }
2348 }
2349 Ok(())
2350 }
2351
2352 fn parse_unicode_escape(&mut self, index: usize) -> Result<char, JsonParseError> {
2353 let scalar = self.parse_hex_quad(index)?;
2354 if (0xD800..=0xDBFF).contains(&scalar) {
2355 if self.next_byte() != Some(b'\\') || self.next_byte() != Some(b'u') {
2356 return Err(JsonParseError::InvalidUnicodeScalar { index });
2357 }
2358 let low = self.parse_hex_quad(index)?;
2359 if !(0xDC00..=0xDFFF).contains(&low) {
2360 return Err(JsonParseError::InvalidUnicodeScalar { index });
2361 }
2362 let high = scalar - 0xD800;
2363 let low = low - 0xDC00;
2364 let combined = 0x10000 + ((high << 10) | low);
2365 char::from_u32(combined).ok_or(JsonParseError::InvalidUnicodeScalar { index })
2366 } else if (0xDC00..=0xDFFF).contains(&scalar) {
2367 Err(JsonParseError::InvalidUnicodeScalar { index })
2368 } else {
2369 char::from_u32(scalar).ok_or(JsonParseError::InvalidUnicodeScalar { index })
2370 }
2371 }
2372
2373 fn parse_hex_quad(&mut self, index: usize) -> Result<u32, JsonParseError> {
2374 let mut value = 0u32;
2375 for _ in 0..4 {
2376 let ch = self.next_byte().ok_or(JsonParseError::UnexpectedEnd)?;
2377 let digit = match ch {
2378 b'0'..=b'9' => (ch - b'0') as u32,
2379 b'a'..=b'f' => 10 + (ch - b'a') as u32,
2380 b'A'..=b'F' => 10 + (ch - b'A') as u32,
2381 _ => return Err(JsonParseError::InvalidUnicodeEscape { index }),
2382 };
2383 value = (value << 4) | digit;
2384 }
2385 Ok(value)
2386 }
2387
2388 fn parse_number(&mut self) -> Result<JsonNumber, JsonParseError> {
2389 let start = self.index;
2390 self.try_consume_byte(b'-');
2391 if self.try_consume_byte(b'0') {
2392 if matches!(self.peek_byte(), Some(b'0'..=b'9')) {
2393 return Err(JsonParseError::InvalidNumber { index: start });
2394 }
2395 } else {
2396 self.consume_digits(start)?;
2397 }
2398
2399 let mut is_float = false;
2400 if self.try_consume_byte(b'.') {
2401 is_float = true;
2402 self.consume_digits(start)?;
2403 }
2404 if matches!(self.peek_byte(), Some(b'e' | b'E')) {
2405 is_float = true;
2406 self.index += 1;
2407 if matches!(self.peek_byte(), Some(b'+' | b'-')) {
2408 self.index += 1;
2409 }
2410 self.consume_digits(start)?;
2411 }
2412
2413 let token = &self.input[start..self.index];
2414 if is_float {
2415 let value = token
2416 .parse::<f64>()
2417 .map_err(|_| JsonParseError::InvalidNumber { index: start })?;
2418 if !value.is_finite() {
2419 return Err(JsonParseError::InvalidNumber { index: start });
2420 }
2421 Ok(JsonNumber::F64(value))
2422 } else if token.starts_with('-') {
2423 let value = token
2424 .parse::<i64>()
2425 .map_err(|_| JsonParseError::InvalidNumber { index: start })?;
2426 Ok(JsonNumber::I64(value))
2427 } else {
2428 let value = token
2429 .parse::<u64>()
2430 .map_err(|_| JsonParseError::InvalidNumber { index: start })?;
2431 Ok(JsonNumber::U64(value))
2432 }
2433 }
2434
2435 fn parse_tape_number(
2436 &mut self,
2437 tokens: &mut Vec<TapeToken>,
2438 parent: Option<usize>,
2439 ) -> Result<usize, JsonParseError> {
2440 let start = self.index;
2441 let _ = self.parse_number()?;
2442 let token_index = tokens.len();
2443 tokens.push(TapeToken {
2444 kind: TapeTokenKind::Number,
2445 start,
2446 end: self.index,
2447 parent,
2448 });
2449 Ok(token_index)
2450 }
2451
2452 fn consume_digits(&mut self, index: usize) -> Result<(), JsonParseError> {
2453 let start = self.index;
2454 while matches!(self.peek_byte(), Some(b'0'..=b'9')) {
2455 self.index += 1;
2456 }
2457 if self.index == start {
2458 return Err(JsonParseError::InvalidNumber { index });
2459 }
2460 Ok(())
2461 }
2462
2463 fn consume_byte(&mut self, expected: u8) -> Result<(), JsonParseError> {
2464 match self.next_byte() {
2465 Some(found) if found == expected => Ok(()),
2466 Some(found) => Err(JsonParseError::UnexpectedCharacter {
2467 index: self.index.saturating_sub(1),
2468 found: found as char,
2469 }),
2470 None => Err(JsonParseError::UnexpectedEnd),
2471 }
2472 }
2473
2474 fn try_consume_byte(&mut self, expected: u8) -> bool {
2475 if self.peek_byte() == Some(expected) {
2476 self.index += 1;
2477 true
2478 } else {
2479 false
2480 }
2481 }
2482
2483 fn skip_whitespace(&mut self) {
2484 while matches!(self.peek_byte(), Some(b' ' | b'\n' | b'\r' | b'\t')) {
2485 self.index += 1;
2486 }
2487 }
2488
2489 fn peek_byte(&self) -> Option<u8> {
2490 self.bytes.get(self.index).copied()
2491 }
2492
2493 fn next_byte(&mut self) -> Option<u8> {
2494 let byte = self.peek_byte()?;
2495 self.index += 1;
2496 Some(byte)
2497 }
2498
2499 fn is_eof(&self) -> bool {
2500 self.index >= self.input.len()
2501 }
2502}
2503
2504#[cfg(test)]
2505mod tests {
2506 use super::*;
2507
2508 #[test]
2509 fn escapes_control_characters_and_quotes() {
2510 let escaped = escape_json_string("hello\t\"world\"\n\u{0007}");
2511 assert_eq!(escaped, "\"hello\\t\\\"world\\\"\\n\\u0007\"");
2512 }
2513
2514 #[test]
2515 fn serializes_nested_values() {
2516 let value = JsonValue::object(vec![
2517 ("name", "node-1".into()),
2518 ("ok", true.into()),
2519 (
2520 "values",
2521 JsonValue::array(vec![1u32.into(), 2u32.into(), JsonValue::Null]),
2522 ),
2523 ]);
2524 assert_eq!(
2525 value.to_json_string().unwrap(),
2526 "{\"name\":\"node-1\",\"ok\":true,\"values\":[1,2,null]}"
2527 );
2528 }
2529
2530 #[test]
2531 fn rejects_non_finite_float() {
2532 let value = JsonValue::from(f64::NAN);
2533 assert_eq!(value.to_json_string(), Err(JsonError::NonFiniteNumber));
2534 }
2535
2536 #[test]
2537 fn parses_basic_json_values() {
2538 assert_eq!(parse_json("null").unwrap(), JsonValue::Null);
2539 assert_eq!(parse_json("true").unwrap(), JsonValue::Bool(true));
2540 assert_eq!(
2541 parse_json("\"hello\"").unwrap(),
2542 JsonValue::String("hello".into())
2543 );
2544 assert_eq!(
2545 parse_json("123").unwrap(),
2546 JsonValue::Number(JsonNumber::U64(123))
2547 );
2548 assert_eq!(
2549 parse_json("-123").unwrap(),
2550 JsonValue::Number(JsonNumber::I64(-123))
2551 );
2552 }
2553
2554 #[test]
2555 fn parses_unicode_and_escapes() {
2556 let value = parse_json("\"line\\n\\u03bb\\uD83D\\uDE80\"").unwrap();
2557 assert_eq!(value, JsonValue::String("line\nλ🚀".into()));
2558 }
2559
2560 #[test]
2561 fn borrowed_parse_avoids_allocating_plain_strings() {
2562 let value = parse_json_borrowed("{\"name\":\"hello\",\"n\":1}").unwrap();
2563 match value {
2564 BorrowedJsonValue::Object(entries) => {
2565 assert!(matches!(entries[0].0, Cow::Borrowed(_)));
2566 assert!(matches!(
2567 entries[0].1,
2568 BorrowedJsonValue::String(Cow::Borrowed(_))
2569 ));
2570 }
2571 other => panic!("unexpected value: {other:?}"),
2572 }
2573 }
2574
2575 #[test]
2576 fn borrowed_parse_allocates_when_unescaping_is_needed() {
2577 let value = parse_json_borrowed("\"line\\nvalue\"").unwrap();
2578 match value {
2579 BorrowedJsonValue::String(Cow::Owned(text)) => assert_eq!(text, "line\nvalue"),
2580 other => panic!("unexpected value: {other:?}"),
2581 }
2582 }
2583
2584 #[test]
2585 fn compiled_schema_serializes_expected_shape() {
2586 let schema = CompiledObjectSchema::new(&["id", "name", "enabled"]);
2587 let values = [
2588 JsonValue::from(7u64),
2589 JsonValue::from("node-7"),
2590 JsonValue::from(true),
2591 ];
2592 let json = schema.to_json_string(values.iter()).unwrap();
2593 assert_eq!(json, "{\"id\":7,\"name\":\"node-7\",\"enabled\":true}");
2594 }
2595
2596 #[test]
2597 fn compiled_row_schema_serializes_array_of_objects() {
2598 let schema = CompiledRowSchema::new(&["id", "name"]);
2599 let row1 = [JsonValue::from(1u64), JsonValue::from("a")];
2600 let row2 = [JsonValue::from(2u64), JsonValue::from("b")];
2601 let json = schema.to_json_string([row1.iter(), row2.iter()]).unwrap();
2602 assert_eq!(json, r#"[{"id":1,"name":"a"},{"id":2,"name":"b"}]"#);
2603 }
2604
2605 #[test]
2606 fn tape_parse_records_structure_tokens() {
2607 let tape = parse_json_tape(r#"{"a":[1,"x"],"b":true}"#).unwrap();
2608 assert_eq!(tape.tokens[0].kind, TapeTokenKind::Object);
2609 assert_eq!(tape.tokens[1].kind, TapeTokenKind::Key);
2610 assert_eq!(tape.tokens[2].kind, TapeTokenKind::Array);
2611 assert_eq!(tape.tokens[3].kind, TapeTokenKind::Number);
2612 assert_eq!(tape.tokens[4].kind, TapeTokenKind::String);
2613 assert_eq!(tape.tokens[5].kind, TapeTokenKind::Key);
2614 assert_eq!(tape.tokens[6].kind, TapeTokenKind::Bool);
2615 }
2616
2617 #[test]
2618 fn tape_object_lookup_finds_child_values() {
2619 let input = r#"{"name":"hello","nested":{"x":1},"flag":true}"#;
2620 let tape = parse_json_tape(input).unwrap();
2621 let root = tape.root(input).unwrap();
2622 let name = root.get("name").unwrap();
2623 assert_eq!(name.kind(), TapeTokenKind::String);
2624 assert_eq!(name.as_str(), Some("hello"));
2625 let nested = root.get("nested").unwrap();
2626 assert_eq!(nested.kind(), TapeTokenKind::Object);
2627 assert!(root.get("missing").is_none());
2628 }
2629
2630 #[test]
2631 fn tape_object_index_lookup_finds_child_values() {
2632 let input = r#"{"name":"hello","nested":{"x":1},"flag":true}"#;
2633 let tape = parse_json_tape(input).unwrap();
2634 let root = tape.root(input).unwrap();
2635 let index = root.build_object_index().unwrap();
2636 let flag = index.get(root, "flag").unwrap();
2637 assert_eq!(flag.kind(), TapeTokenKind::Bool);
2638 assert!(index.get(root, "missing").is_none());
2639 }
2640
2641 #[test]
2642 fn indexed_tape_object_compiled_lookup_finds_child_values() {
2643 let input = r#"{"name":"hello","nested":{"x":1},"flag":true}"#;
2644 let tape = parse_json_tape(input).unwrap();
2645 let root = tape.root(input).unwrap();
2646 let index = root.build_object_index().unwrap();
2647 let indexed = root.with_index(&index);
2648 let keys = CompiledTapeKeys::new(&["name", "flag", "missing"]);
2649 let got = indexed
2650 .get_compiled_many(&keys)
2651 .map(|value| value.map(|value| value.kind()))
2652 .collect::<Vec<_>>();
2653 assert_eq!(got, vec![Some(TapeTokenKind::String), Some(TapeTokenKind::Bool), None]);
2654 }
2655
2656 #[test]
2657 fn serde_style_convenience_api_works() {
2658 let value = from_str(r#"{"ok":true,"n":7,"items":[1,2,3],"msg":"hello"}"#).unwrap();
2659 assert!(value.is_object());
2660 assert_eq!(value["ok"].as_bool(), Some(true));
2661 assert_eq!(value["n"].as_i64(), Some(7));
2662 assert_eq!(value["msg"].as_str(), Some("hello"));
2663 assert_eq!(value["items"][1].as_u64(), Some(2));
2664 assert!(value["missing"].is_null());
2665 assert_eq!(to_string(&value).unwrap(), r#"{"ok":true,"n":7,"items":[1,2,3],"msg":"hello"}"#);
2666 assert_eq!(from_slice(br#"[1,true,"x"]"#).unwrap()[2].as_str(), Some("x"));
2667 assert_eq!(to_vec(&value).unwrap(), value.to_json_string().unwrap().into_bytes());
2668 }
2669
2670 #[test]
2671 fn json_macro_builds_values() {
2672 let value = json!({"ok": true, "items": [1, 2, null], "msg": "x"});
2673 assert_eq!(value["ok"].as_bool(), Some(true));
2674 assert_eq!(value["items"][0].as_u64(), Some(1));
2675 assert!(value["items"][2].is_null());
2676 assert_eq!(value["msg"].as_str(), Some("x"));
2677 }
2678
2679 #[test]
2680 fn from_slice_rejects_invalid_utf8() {
2681 assert!(matches!(from_slice(&[0xff]), Err(JsonParseError::InvalidUtf8)));
2682 }
2683
2684 #[test]
2685 fn pointer_take_and_pretty_helpers_work() {
2686 let mut value = from_str(r#"{"a":{"b":[10,20,{"~key/":"x"}]}}"#).unwrap();
2687 assert_eq!(value.pointer("/a/b/1").and_then(JsonValue::as_u64), Some(20));
2688 assert_eq!(value.pointer("/a/b/2/~0key~1").and_then(JsonValue::as_str), Some("x"));
2689 *value.pointer_mut("/a/b/0").unwrap() = JsonValue::from(99u64);
2690 assert_eq!(value.pointer("/a/b/0").and_then(JsonValue::as_u64), Some(99));
2691
2692 let taken = value.pointer_mut("/a/b/2").unwrap().take();
2693 assert!(value.pointer("/a/b/2").unwrap().is_null());
2694 assert_eq!(taken["~key/"].as_str(), Some("x"));
2695
2696 let pretty = to_string_pretty(&value).unwrap();
2697 assert!(pretty.contains("\"a\": {"));
2698 let mut out = Vec::new();
2699 to_writer_pretty(&mut out, &value).unwrap();
2700 assert_eq!(String::from_utf8(out).unwrap(), pretty);
2701 }
2702
2703 #[test]
2704 fn reader_writer_and_collection_helpers_work() {
2705 let value = from_reader(std::io::Cursor::new(br#"{"a":1,"b":[true,false]}"# as &[u8])).unwrap();
2706 assert_eq!(value["a"].as_u64(), Some(1));
2707 assert_eq!(value["b"].len(), 2);
2708 assert_eq!(value["b"].get_index(1).and_then(JsonValue::as_bool), Some(false));
2709
2710 let mut out = Vec::new();
2711 to_writer(&mut out, &value).unwrap();
2712 assert_eq!(String::from_utf8(out).unwrap(), value.to_json_string().unwrap());
2713
2714 let object = JsonValue::from_iter([("x", 1u64), ("y", 2u64)]);
2715 assert_eq!(object["x"].as_u64(), Some(1));
2716 let array = JsonValue::from_iter([1u64, 2u64, 3u64]);
2717 assert_eq!(array.get_index(2).and_then(JsonValue::as_u64), Some(3));
2718 }
2719
2720 #[test]
2721 fn json_macro_expr_key_parity_works() {
2722 let code = 200;
2723 let features = vec!["serde", "json"];
2724 let value = json!({
2725 "code": code,
2726 "success": code == 200,
2727 features[0]: features[1],
2728 });
2729 assert_eq!(value["code"], 200);
2730 assert_eq!(value["success"], true);
2731 assert_eq!(value["serde"], "json");
2732 }
2733
2734#[test]
2735 fn primitive_partial_eq_parity_works() {
2736 let value = json!({"n": 1, "f": 2.5, "b": true, "s": "x"});
2737 assert_eq!(value["n"], 1);
2738 assert_eq!(1, value["n"]);
2739 assert_eq!(value["f"], 2.5);
2740 assert_eq!(value["b"], true);
2741 assert_eq!(value["s"], "x");
2742 assert_eq!(String::from("x"), value["s"]);
2743 }
2744
2745 #[test]
2746 fn signature_and_sort_parity_helpers_work() {
2747 let mut value = json!({"z": {"b": 2, "a": 1}, "a": [{"d": 4, "c": 3}]});
2748 assert_eq!(value.as_object().unwrap().len(), 2);
2749 assert_eq!(value["a"].as_array().unwrap().len(), 1);
2750 value.sort_all_objects();
2751 let root_keys = value.as_object().unwrap().iter().map(|(k, _)| k.as_str()).collect::<Vec<_>>();
2752 assert_eq!(root_keys, vec!["a", "z"]);
2753 let nested_keys = value["z"].as_object().unwrap().iter().map(|(k, _)| k.as_str()).collect::<Vec<_>>();
2754 assert_eq!(nested_keys, vec!["a", "b"]);
2755 }
2756
2757 #[test]
2758 fn generic_get_and_get_mut_index_parity_work() {
2759 let mut value = json!({"obj": {"x": 1}, "arr": [10, 20, 30]});
2760 let key = String::from("obj");
2761 assert_eq!(value.get("obj").and_then(|v| v.get("x")).and_then(JsonValue::as_u64), Some(1));
2762 assert_eq!(value.get(&key).and_then(|v| v.get("x")).and_then(JsonValue::as_u64), Some(1));
2763 assert_eq!(value.get("arr").and_then(|v| v.get(1)).and_then(JsonValue::as_u64), Some(20));
2764 *value.get_mut("arr").unwrap().get_mut(2).unwrap() = JsonValue::from(99u64);
2765 assert_eq!(value["arr"][2].as_u64(), Some(99));
2766 }
2767
2768 #[test]
2769 fn number_and_mut_index_parity_helpers_work() {
2770 let int = JsonValue::from(7i64);
2771 assert!(int.is_i64());
2772 assert!(!int.is_u64());
2773 assert!(!int.is_f64());
2774 assert_eq!(int.as_number().and_then(JsonNumber::as_i64), Some(7));
2775
2776 let float = JsonValue::Number(JsonNumber::from_f64(2.5).unwrap());
2777 assert!(float.is_f64());
2778 assert_eq!(float.as_f64(), Some(2.5));
2779 assert_eq!(JsonValue::Null.as_null(), Some(()));
2780
2781 let mut value = JsonValue::Null;
2782 value["a"]["b"]["c"] = JsonValue::from(true);
2783 assert_eq!(value.pointer("/a/b/c").and_then(JsonValue::as_bool), Some(true));
2784
2785 value["arr"] = json!([1, 2, 3]);
2786 value["arr"][1] = JsonValue::from(9u64);
2787 assert_eq!(value.pointer("/arr/1").and_then(JsonValue::as_u64), Some(9));
2788 }
2789
2790 #[test]
2791 fn rejects_invalid_json_inputs() {
2792 assert!(matches!(
2793 parse_json("{"),
2794 Err(JsonParseError::UnexpectedEnd)
2795 ));
2796 assert!(matches!(
2797 parse_json("{\"a\" 1}"),
2798 Err(JsonParseError::ExpectedColon { .. })
2799 ));
2800 assert!(matches!(
2801 parse_json("[1 2]"),
2802 Err(JsonParseError::ExpectedCommaOrEnd {
2803 context: "array",
2804 ..
2805 })
2806 ));
2807 assert!(matches!(
2808 parse_json("{\"a\":1 trailing"),
2809 Err(JsonParseError::ExpectedCommaOrEnd {
2810 context: "object",
2811 ..
2812 })
2813 ));
2814 assert!(matches!(
2815 parse_json("00"),
2816 Err(JsonParseError::InvalidNumber { .. })
2817 ));
2818 }
2819
2820 #[test]
2821 fn roundtrips_specific_structures() {
2822 let values = [
2823 JsonValue::Null,
2824 JsonValue::Bool(false),
2825 JsonValue::String("tab\tquote\"slash\\snowman☃".into()),
2826 JsonValue::Number(JsonNumber::I64(-9_223_372_036_854_775_808)),
2827 JsonValue::Number(JsonNumber::U64(u64::MAX)),
2828 JsonValue::Number(JsonNumber::F64(12345.125)),
2829 JsonValue::Array(vec![
2830 JsonValue::Bool(true),
2831 JsonValue::String("nested".into()),
2832 JsonValue::Object(vec![("x".into(), 1u64.into())]),
2833 ]),
2834 ];
2835 for value in values {
2836 let text = value.to_json_string().unwrap();
2837 let reparsed = parse_json(&text).unwrap();
2838 assert_json_equivalent(&value, &reparsed);
2839 }
2840 }
2841
2842 #[test]
2843 fn deterministic_fuzz_roundtrip_strings_and_values() {
2844 let mut rng = Rng::new(0x5eed_1234_5678_9abc);
2845 for _ in 0..2_000 {
2846 let input = random_string(&mut rng, 48);
2847 let escaped = escape_json_string(&input);
2848 let parsed = parse_json(&escaped).unwrap();
2849 assert_eq!(parsed, JsonValue::String(input));
2850 }
2851
2852 for _ in 0..1_000 {
2853 let value = random_json_value(&mut rng, 0, 4);
2854 let text = value.to_json_string().unwrap();
2855 let reparsed = parse_json(&text).unwrap();
2856 assert_json_equivalent(&value, &reparsed);
2857 }
2858 }
2859
2860 fn assert_json_equivalent(expected: &JsonValue, actual: &JsonValue) {
2861 match (expected, actual) {
2862 (JsonValue::Null, JsonValue::Null) => {}
2863 (JsonValue::Bool(a), JsonValue::Bool(b)) => assert_eq!(a, b),
2864 (JsonValue::String(a), JsonValue::String(b)) => assert_eq!(a, b),
2865 (JsonValue::Number(a), JsonValue::Number(b)) => assert_numbers_equivalent(a, b),
2866 (JsonValue::Array(a), JsonValue::Array(b)) => {
2867 assert_eq!(a.len(), b.len());
2868 for (left, right) in a.iter().zip(b.iter()) {
2869 assert_json_equivalent(left, right);
2870 }
2871 }
2872 (JsonValue::Object(a), JsonValue::Object(b)) => {
2873 assert_eq!(a.len(), b.len());
2874 for ((left_key, left_value), (right_key, right_value)) in a.iter().zip(b.iter()) {
2875 assert_eq!(left_key, right_key);
2876 assert_json_equivalent(left_value, right_value);
2877 }
2878 }
2879 _ => panic!("json values differ: expected {expected:?}, actual {actual:?}"),
2880 }
2881 }
2882
2883 fn assert_numbers_equivalent(expected: &JsonNumber, actual: &JsonNumber) {
2884 match (expected, actual) {
2885 (JsonNumber::I64(a), JsonNumber::I64(b)) => assert_eq!(a, b),
2886 (JsonNumber::U64(a), JsonNumber::U64(b)) => assert_eq!(a, b),
2887 (JsonNumber::F64(a), JsonNumber::F64(b)) => assert_eq!(a.to_bits(), b.to_bits()),
2888 (JsonNumber::I64(a), JsonNumber::U64(b)) if *a >= 0 => assert_eq!(*a as u64, *b),
2889 (JsonNumber::U64(a), JsonNumber::I64(b)) if *b >= 0 => assert_eq!(*a, *b as u64),
2890 (JsonNumber::I64(a), JsonNumber::F64(b)) => assert_eq!(*a as f64, *b),
2891 (JsonNumber::U64(a), JsonNumber::F64(b)) => assert_eq!(*a as f64, *b),
2892 (JsonNumber::F64(a), JsonNumber::I64(b)) => assert_eq!(*a, *b as f64),
2893 (JsonNumber::F64(a), JsonNumber::U64(b)) => assert_eq!(*a, *b as f64),
2894 (left, right) => panic!("json numbers differ: expected {left:?}, actual {right:?}"),
2895 }
2896 }
2897
2898 #[derive(Clone, Debug)]
2899 struct Rng {
2900 state: u64,
2901 }
2902
2903 impl Rng {
2904 fn new(seed: u64) -> Self {
2905 Self { state: seed }
2906 }
2907
2908 fn next_u64(&mut self) -> u64 {
2909 self.state = self
2910 .state
2911 .wrapping_mul(6364136223846793005)
2912 .wrapping_add(1442695040888963407);
2913 self.state
2914 }
2915
2916 fn choose(&mut self, upper_exclusive: usize) -> usize {
2917 (self.next_u64() % upper_exclusive as u64) as usize
2918 }
2919
2920 fn bool(&mut self) -> bool {
2921 (self.next_u64() & 1) == 1
2922 }
2923 }
2924
2925 fn random_string(rng: &mut Rng, max_len: usize) -> String {
2926 let len = rng.choose(max_len + 1);
2927 let mut out = String::new();
2928 for _ in 0..len {
2929 let ch = match rng.choose(12) {
2930 0 => '"',
2931 1 => '\\',
2932 2 => '\n',
2933 3 => '\r',
2934 4 => '\t',
2935 5 => '\u{0007}',
2936 6 => 'λ',
2937 7 => '🚀',
2938 8 => '☃',
2939 _ => (b'a' + rng.choose(26) as u8) as char,
2940 };
2941 out.push(ch);
2942 }
2943 out
2944 }
2945
2946 fn random_json_value(rng: &mut Rng, depth: usize, max_depth: usize) -> JsonValue {
2947 if depth >= max_depth {
2948 return random_leaf(rng);
2949 }
2950 match rng.choose(7) {
2951 0 | 1 | 2 | 3 => random_leaf(rng),
2952 4 => {
2953 let len = rng.choose(5);
2954 let mut values = Vec::with_capacity(len);
2955 for _ in 0..len {
2956 values.push(random_json_value(rng, depth + 1, max_depth));
2957 }
2958 JsonValue::Array(values)
2959 }
2960 _ => {
2961 let len = rng.choose(5);
2962 let mut entries = Vec::with_capacity(len);
2963 for index in 0..len {
2964 entries.push((
2965 format!("k{depth}_{index}_{}", random_string(rng, 6)),
2966 random_json_value(rng, depth + 1, max_depth),
2967 ));
2968 }
2969 JsonValue::Object(entries)
2970 }
2971 }
2972 }
2973
2974 fn random_leaf(rng: &mut Rng) -> JsonValue {
2975 match rng.choose(6) {
2976 0 => JsonValue::Null,
2977 1 => JsonValue::Bool(rng.bool()),
2978 2 => JsonValue::String(random_string(rng, 24)),
2979 3 => JsonValue::Number(JsonNumber::I64(
2980 (rng.next_u64() >> 1) as i64 * if rng.bool() { 1 } else { -1 },
2981 )),
2982 4 => JsonValue::Number(JsonNumber::U64(rng.next_u64())),
2983 _ => {
2984 let mantissa = (rng.next_u64() % 1_000_000) as f64 / 1000.0;
2985 let sign = if rng.bool() { 1.0 } else { -1.0 };
2986 JsonValue::Number(JsonNumber::F64(sign * mantissa))
2987 }
2988 }
2989 }
2990}