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 {
1310 (null) => {
1311 $crate::JsonValue::Null
1312 };
1313 ([$($element:tt),* $(,)?]) => {
1314 $crate::JsonValue::Array(vec![$($crate::json!($element)),*])
1315 };
1316 ({$($key:literal : $value:tt),* $(,)?}) => {
1317 $crate::JsonValue::Object(vec![$(($key.to_owned(), $crate::json!($value))),*])
1318 };
1319 ($other:expr) => {
1320 $crate::JsonValue::from($other)
1321 };
1322}
1323
1324fn decode_pointer_segment(segment: &str) -> String {
1325 let mut out = String::with_capacity(segment.len());
1326 let bytes = segment.as_bytes();
1327 let mut i = 0;
1328 while i < bytes.len() {
1329 if bytes[i] == b'~' && i + 1 < bytes.len() {
1330 match bytes[i + 1] {
1331 b'0' => {
1332 out.push('~');
1333 i += 2;
1334 continue;
1335 }
1336 b'1' => {
1337 out.push('/');
1338 i += 2;
1339 continue;
1340 }
1341 _ => {}
1342 }
1343 }
1344 out.push(bytes[i] as char);
1345 i += 1;
1346 }
1347 out
1348}
1349
1350fn write_indent(out: &mut Vec<u8>, depth: usize) {
1351 for _ in 0..depth {
1352 out.extend_from_slice(b" ");
1353 }
1354}
1355
1356fn write_json_value_pretty(out: &mut Vec<u8>, value: &JsonValue, depth: usize) -> Result<(), JsonError> {
1357 match value {
1358 JsonValue::Null | JsonValue::Bool(_) | JsonValue::Number(_) | JsonValue::String(_) => {
1359 write_json_value(out, value)
1360 }
1361 JsonValue::Array(values) => {
1362 out.push(b'[');
1363 if !values.is_empty() {
1364 out.push(b'\n');
1365 for (index, value) in values.iter().enumerate() {
1366 if index > 0 {
1367 out.extend_from_slice(b",\n");
1368 }
1369 write_indent(out, depth + 1);
1370 write_json_value_pretty(out, value, depth + 1)?;
1371 }
1372 out.push(b'\n');
1373 write_indent(out, depth);
1374 }
1375 out.push(b']');
1376 Ok(())
1377 }
1378 JsonValue::Object(entries) => {
1379 out.push(b'{');
1380 if !entries.is_empty() {
1381 out.push(b'\n');
1382 for (index, (key, value)) in entries.iter().enumerate() {
1383 if index > 0 {
1384 out.extend_from_slice(b",\n");
1385 }
1386 write_indent(out, depth + 1);
1387 write_json_key(out, key);
1388 out.push(b' ');
1389 write_json_value_pretty(out, value, depth + 1)?;
1390 }
1391 out.push(b'\n');
1392 write_indent(out, depth);
1393 }
1394 out.push(b'}');
1395 Ok(())
1396 }
1397 }
1398}
1399
1400fn hash_key(bytes: &[u8]) -> u64 {
1401 let mut hash = 1469598103934665603u64;
1402 for &byte in bytes {
1403 hash ^= byte as u64;
1404 hash = hash.wrapping_mul(1099511628211u64);
1405 }
1406 hash
1407}
1408
1409#[inline]
1410fn write_json_value(out: &mut Vec<u8>, value: &JsonValue) -> Result<(), JsonError> {
1411 match value {
1412 JsonValue::Null => out.extend_from_slice(b"null"),
1413 JsonValue::Bool(value) => {
1414 if *value {
1415 out.extend_from_slice(b"true");
1416 } else {
1417 out.extend_from_slice(b"false");
1418 }
1419 }
1420 JsonValue::Number(number) => write_json_number(out, number)?,
1421 JsonValue::String(value) => {
1422 write_escaped_json_string(out, value);
1423 }
1424 JsonValue::Array(values) => {
1425 write_json_array(out, values)?;
1426 }
1427 JsonValue::Object(entries) => {
1428 write_json_object(out, entries)?;
1429 }
1430 }
1431 Ok(())
1432}
1433
1434#[inline]
1435fn write_json_number(out: &mut Vec<u8>, value: &JsonNumber) -> Result<(), JsonError> {
1436 match value {
1437 JsonNumber::I64(value) => {
1438 append_i64(out, *value);
1439 Ok(())
1440 }
1441 JsonNumber::U64(value) => {
1442 append_u64(out, *value);
1443 Ok(())
1444 }
1445 JsonNumber::F64(value) => {
1446 if !value.is_finite() {
1447 return Err(JsonError::NonFiniteNumber);
1448 }
1449 out.extend_from_slice(value.to_string().as_bytes());
1450 Ok(())
1451 }
1452 }
1453}
1454
1455#[inline]
1456fn write_escaped_json_string(out: &mut Vec<u8>, input: &str) {
1457 out.push(b'"');
1458 let bytes = input.as_bytes();
1459 let mut fast_index = 0usize;
1460 while fast_index < bytes.len() {
1461 let byte = bytes[fast_index];
1462 if needs_escape(byte) {
1463 break;
1464 }
1465 fast_index += 1;
1466 }
1467 if fast_index == bytes.len() {
1468 out.extend_from_slice(bytes);
1469 out.push(b'"');
1470 return;
1471 }
1472
1473 if fast_index > 0 {
1474 out.extend_from_slice(&bytes[..fast_index]);
1475 }
1476
1477 let mut chunk_start = fast_index;
1478 for (index, byte) in bytes.iter().copied().enumerate().skip(fast_index) {
1479 let escape = match byte {
1480 b'"' => Some(br#"\""#.as_slice()),
1481 b'\\' => Some(br#"\\"#.as_slice()),
1482 0x08 => Some(br#"\b"#.as_slice()),
1483 0x0c => Some(br#"\f"#.as_slice()),
1484 b'\n' => Some(br#"\n"#.as_slice()),
1485 b'\r' => Some(br#"\r"#.as_slice()),
1486 b'\t' => Some(br#"\t"#.as_slice()),
1487 _ => None,
1488 };
1489 if let Some(escape) = escape {
1490 if chunk_start < index {
1491 out.extend_from_slice(&bytes[chunk_start..index]);
1492 }
1493 out.extend_from_slice(escape);
1494 chunk_start = index + 1;
1495 continue;
1496 }
1497 if byte <= 0x1f {
1498 if chunk_start < index {
1499 out.extend_from_slice(&bytes[chunk_start..index]);
1500 }
1501 out.extend_from_slice(br#"\u00"#);
1502 out.push(hex_digit((byte >> 4) & 0x0f));
1503 out.push(hex_digit(byte & 0x0f));
1504 chunk_start = index + 1;
1505 }
1506 }
1507 if chunk_start < input.len() {
1508 out.extend_from_slice(&bytes[chunk_start..]);
1509 }
1510 out.push(b'"');
1511}
1512
1513#[inline]
1514fn needs_escape(byte: u8) -> bool {
1515 matches!(byte, b'"' | b'\\' | 0x00..=0x1f)
1516}
1517
1518#[inline]
1519fn write_json_array(out: &mut Vec<u8>, values: &[JsonValue]) -> Result<(), JsonError> {
1520 out.push(b'[');
1521 match values {
1522 [] => {}
1523 [one] => {
1524 write_json_value(out, one)?;
1525 }
1526 [a, b] => {
1527 write_json_value(out, a)?;
1528 out.push(b',');
1529 write_json_value(out, b)?;
1530 }
1531 [a, b, c] => {
1532 write_json_value(out, a)?;
1533 out.push(b',');
1534 write_json_value(out, b)?;
1535 out.push(b',');
1536 write_json_value(out, c)?;
1537 }
1538 _ => {
1539 let mut iter = values.iter();
1540 if let Some(first) = iter.next() {
1541 write_json_value(out, first)?;
1542 for value in iter {
1543 out.push(b',');
1544 write_json_value(out, value)?;
1545 }
1546 }
1547 }
1548 }
1549 out.push(b']');
1550 Ok(())
1551}
1552
1553#[inline]
1554fn write_json_object(out: &mut Vec<u8>, entries: &[(String, JsonValue)]) -> Result<(), JsonError> {
1555 out.push(b'{');
1556 match entries {
1557 [] => {}
1558 [(k1, v1)] => {
1559 write_json_key(out, k1);
1560 write_json_value(out, v1)?;
1561 }
1562 [(k1, v1), (k2, v2)] => {
1563 write_json_key(out, k1);
1564 write_json_value(out, v1)?;
1565 out.push(b',');
1566 write_json_key(out, k2);
1567 write_json_value(out, v2)?;
1568 }
1569 [(k1, v1), (k2, v2), (k3, v3)] => {
1570 write_json_key(out, k1);
1571 write_json_value(out, v1)?;
1572 out.push(b',');
1573 write_json_key(out, k2);
1574 write_json_value(out, v2)?;
1575 out.push(b',');
1576 write_json_key(out, k3);
1577 write_json_value(out, v3)?;
1578 }
1579 _ => {
1580 let mut iter = entries.iter();
1581 if let Some((first_key, first_value)) = iter.next() {
1582 write_json_key(out, first_key);
1583 write_json_value(out, first_value)?;
1584 for (key, value) in iter {
1585 out.push(b',');
1586 write_json_key(out, key);
1587 write_json_value(out, value)?;
1588 }
1589 }
1590 }
1591 }
1592 out.push(b'}');
1593 Ok(())
1594}
1595
1596#[inline]
1597fn write_json_key(out: &mut Vec<u8>, key: &str) {
1598 let bytes = key.as_bytes();
1599 if is_plain_json_string(bytes) {
1600 out.push(b'"');
1601 out.extend_from_slice(bytes);
1602 out.extend_from_slice(b"\":");
1603 } else {
1604 write_escaped_json_string(out, key);
1605 out.push(b':');
1606 }
1607}
1608
1609#[inline]
1610fn is_plain_json_string(bytes: &[u8]) -> bool {
1611 for &byte in bytes {
1612 if needs_escape(byte) {
1613 return false;
1614 }
1615 }
1616 true
1617}
1618
1619fn initial_json_capacity(value: &JsonValue) -> usize {
1620 match value {
1621 JsonValue::Null => 4,
1622 JsonValue::Bool(true) => 4,
1623 JsonValue::Bool(false) => 5,
1624 JsonValue::Number(JsonNumber::I64(value)) => estimate_i64_len(*value),
1625 JsonValue::Number(JsonNumber::U64(value)) => estimate_u64_len(*value),
1626 JsonValue::Number(JsonNumber::F64(_)) => 24,
1627 JsonValue::String(value) => estimate_escaped_string_len(value),
1628 JsonValue::Array(values) => 2 + values.len().saturating_mul(16),
1629 JsonValue::Object(entries) => {
1630 2 + entries
1631 .iter()
1632 .map(|(key, _)| estimate_escaped_string_len(key) + 8)
1633 .sum::<usize>()
1634 }
1635 }
1636}
1637
1638fn estimate_escaped_string_len(value: &str) -> usize {
1639 let mut len = 2;
1640 for ch in value.chars() {
1641 len += match ch {
1642 '"' | '\\' | '\u{08}' | '\u{0C}' | '\n' | '\r' | '\t' => 2,
1643 ch if ch <= '\u{1F}' => 6,
1644 ch => ch.len_utf8(),
1645 };
1646 }
1647 len
1648}
1649
1650fn estimate_u64_len(mut value: u64) -> usize {
1651 let mut len = 1;
1652 while value >= 10 {
1653 value /= 10;
1654 len += 1;
1655 }
1656 len
1657}
1658
1659fn estimate_i64_len(value: i64) -> usize {
1660 if value < 0 {
1661 1 + estimate_u64_len(value.unsigned_abs())
1662 } else {
1663 estimate_u64_len(value as u64)
1664 }
1665}
1666
1667fn append_i64(out: &mut Vec<u8>, value: i64) {
1668 if value < 0 {
1669 out.push(b'-');
1670 append_u64(out, value.unsigned_abs());
1671 } else {
1672 append_u64(out, value as u64);
1673 }
1674}
1675
1676fn append_u64(out: &mut Vec<u8>, mut value: u64) {
1677 let mut buf = [0u8; 20];
1678 let mut index = buf.len();
1679 loop {
1680 index -= 1;
1681 buf[index] = b'0' + (value % 10) as u8;
1682 value /= 10;
1683 if value == 0 {
1684 break;
1685 }
1686 }
1687 out.extend_from_slice(&buf[index..]);
1688}
1689
1690fn hex_digit(value: u8) -> u8 {
1691 match value {
1692 0..=9 => b'0' + value,
1693 10..=15 => b'a' + (value - 10),
1694 _ => unreachable!(),
1695 }
1696}
1697
1698struct Parser<'a> {
1699 input: &'a str,
1700 bytes: &'a [u8],
1701 index: usize,
1702}
1703
1704impl<'a> Parser<'a> {
1705 fn new(input: &'a str) -> Self {
1706 Self {
1707 input,
1708 bytes: input.as_bytes(),
1709 index: 0,
1710 }
1711 }
1712
1713 fn parse_value(&mut self) -> Result<JsonValue, JsonParseError> {
1714 self.skip_whitespace();
1715 match self.peek_byte() {
1716 Some(b'n') => self.parse_literal(b"null", JsonValue::Null),
1717 Some(b't') => self.parse_literal(b"true", JsonValue::Bool(true)),
1718 Some(b'f') => self.parse_literal(b"false", JsonValue::Bool(false)),
1719 Some(b'"') => Ok(JsonValue::String(self.parse_string()?)),
1720 Some(b'[') => self.parse_array(),
1721 Some(b'{') => self.parse_object(),
1722 Some(b'-' | b'0'..=b'9') => self.parse_number().map(JsonValue::Number),
1723 Some(found) => Err(JsonParseError::UnexpectedCharacter {
1724 index: self.index,
1725 found: found as char,
1726 }),
1727 None => Err(JsonParseError::UnexpectedEnd),
1728 }
1729 }
1730
1731 fn parse_value_borrowed(&mut self) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1732 self.skip_whitespace();
1733 match self.peek_byte() {
1734 Some(b'n') => self.parse_literal_borrowed(b"null", BorrowedJsonValue::Null),
1735 Some(b't') => self.parse_literal_borrowed(b"true", BorrowedJsonValue::Bool(true)),
1736 Some(b'f') => self.parse_literal_borrowed(b"false", BorrowedJsonValue::Bool(false)),
1737 Some(b'"') => Ok(BorrowedJsonValue::String(self.parse_string_borrowed()?)),
1738 Some(b'[') => self.parse_array_borrowed(),
1739 Some(b'{') => self.parse_object_borrowed(),
1740 Some(b'-' | b'0'..=b'9') => self.parse_number().map(BorrowedJsonValue::Number),
1741 Some(found) => Err(JsonParseError::UnexpectedCharacter {
1742 index: self.index,
1743 found: found as char,
1744 }),
1745 None => Err(JsonParseError::UnexpectedEnd),
1746 }
1747 }
1748
1749 fn parse_tape_value(
1750 &mut self,
1751 tokens: &mut Vec<TapeToken>,
1752 parent: Option<usize>,
1753 ) -> Result<usize, JsonParseError> {
1754 self.skip_whitespace();
1755 match self.peek_byte() {
1756 Some(b'n') => self.parse_tape_literal(tokens, parent, b"null", TapeTokenKind::Null),
1757 Some(b't') => self.parse_tape_literal(tokens, parent, b"true", TapeTokenKind::Bool),
1758 Some(b'f') => self.parse_tape_literal(tokens, parent, b"false", TapeTokenKind::Bool),
1759 Some(b'"') => self.parse_tape_string(tokens, parent, TapeTokenKind::String),
1760 Some(b'[') => self.parse_tape_array(tokens, parent),
1761 Some(b'{') => self.parse_tape_object(tokens, parent),
1762 Some(b'-' | b'0'..=b'9') => self.parse_tape_number(tokens, parent),
1763 Some(found) => Err(JsonParseError::UnexpectedCharacter {
1764 index: self.index,
1765 found: found as char,
1766 }),
1767 None => Err(JsonParseError::UnexpectedEnd),
1768 }
1769 }
1770
1771 fn parse_literal(
1772 &mut self,
1773 expected: &[u8],
1774 value: JsonValue,
1775 ) -> Result<JsonValue, JsonParseError> {
1776 if self.bytes[self.index..].starts_with(expected) {
1777 self.index += expected.len();
1778 Ok(value)
1779 } else {
1780 Err(JsonParseError::InvalidLiteral { index: self.index })
1781 }
1782 }
1783
1784 fn parse_literal_borrowed(
1785 &mut self,
1786 expected: &[u8],
1787 value: BorrowedJsonValue<'a>,
1788 ) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1789 if self.bytes[self.index..].starts_with(expected) {
1790 self.index += expected.len();
1791 Ok(value)
1792 } else {
1793 Err(JsonParseError::InvalidLiteral { index: self.index })
1794 }
1795 }
1796
1797 fn parse_tape_literal(
1798 &mut self,
1799 tokens: &mut Vec<TapeToken>,
1800 parent: Option<usize>,
1801 expected: &[u8],
1802 kind: TapeTokenKind,
1803 ) -> Result<usize, JsonParseError> {
1804 let start = self.index;
1805 if self.bytes[self.index..].starts_with(expected) {
1806 self.index += expected.len();
1807 let token_index = tokens.len();
1808 tokens.push(TapeToken {
1809 kind,
1810 start,
1811 end: self.index,
1812 parent,
1813 });
1814 Ok(token_index)
1815 } else {
1816 Err(JsonParseError::InvalidLiteral { index: self.index })
1817 }
1818 }
1819
1820 fn parse_array(&mut self) -> Result<JsonValue, JsonParseError> {
1821 self.consume_byte(b'[')?;
1822 self.skip_whitespace();
1823 let mut values = Vec::new();
1824 if self.try_consume_byte(b']') {
1825 return Ok(JsonValue::Array(values));
1826 }
1827 loop {
1828 values.push(self.parse_value()?);
1829 self.skip_whitespace();
1830 if self.try_consume_byte(b']') {
1831 break;
1832 }
1833 if !self.try_consume_byte(b',') {
1834 return Err(JsonParseError::ExpectedCommaOrEnd {
1835 index: self.index,
1836 context: "array",
1837 });
1838 }
1839 self.skip_whitespace();
1840 }
1841 Ok(JsonValue::Array(values))
1842 }
1843
1844 fn parse_array_borrowed(&mut self) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1845 self.consume_byte(b'[')?;
1846 self.skip_whitespace();
1847 let mut values = Vec::new();
1848 if self.try_consume_byte(b']') {
1849 return Ok(BorrowedJsonValue::Array(values));
1850 }
1851 loop {
1852 values.push(self.parse_value_borrowed()?);
1853 self.skip_whitespace();
1854 if self.try_consume_byte(b']') {
1855 break;
1856 }
1857 if !self.try_consume_byte(b',') {
1858 return Err(JsonParseError::ExpectedCommaOrEnd {
1859 index: self.index,
1860 context: "array",
1861 });
1862 }
1863 self.skip_whitespace();
1864 }
1865 Ok(BorrowedJsonValue::Array(values))
1866 }
1867
1868 fn parse_tape_array(
1869 &mut self,
1870 tokens: &mut Vec<TapeToken>,
1871 parent: Option<usize>,
1872 ) -> Result<usize, JsonParseError> {
1873 let start = self.index;
1874 self.consume_byte(b'[')?;
1875 let token_index = tokens.len();
1876 tokens.push(TapeToken {
1877 kind: TapeTokenKind::Array,
1878 start,
1879 end: start,
1880 parent,
1881 });
1882 self.skip_whitespace();
1883 if self.try_consume_byte(b']') {
1884 tokens[token_index].end = self.index;
1885 return Ok(token_index);
1886 }
1887 loop {
1888 self.parse_tape_value(tokens, Some(token_index))?;
1889 self.skip_whitespace();
1890 if self.try_consume_byte(b']') {
1891 tokens[token_index].end = self.index;
1892 break;
1893 }
1894 if !self.try_consume_byte(b',') {
1895 return Err(JsonParseError::ExpectedCommaOrEnd {
1896 index: self.index,
1897 context: "array",
1898 });
1899 }
1900 self.skip_whitespace();
1901 }
1902 Ok(token_index)
1903 }
1904
1905 fn parse_object(&mut self) -> Result<JsonValue, JsonParseError> {
1906 self.consume_byte(b'{')?;
1907 self.skip_whitespace();
1908 let mut entries = Vec::new();
1909 if self.try_consume_byte(b'}') {
1910 return Ok(JsonValue::Object(entries));
1911 }
1912 loop {
1913 if self.peek_byte() != Some(b'"') {
1914 return match self.peek_byte() {
1915 Some(found) => Err(JsonParseError::UnexpectedCharacter {
1916 index: self.index,
1917 found: found as char,
1918 }),
1919 None => Err(JsonParseError::UnexpectedEnd),
1920 };
1921 }
1922 let key = self.parse_string()?;
1923 self.skip_whitespace();
1924 if !self.try_consume_byte(b':') {
1925 return Err(JsonParseError::ExpectedColon { index: self.index });
1926 }
1927 let value = self.parse_value()?;
1928 entries.push((key, 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: "object",
1937 });
1938 }
1939 self.skip_whitespace();
1940 }
1941 Ok(JsonValue::Object(entries))
1942 }
1943
1944 fn parse_object_borrowed(&mut self) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1945 self.consume_byte(b'{')?;
1946 self.skip_whitespace();
1947 let mut entries = Vec::new();
1948 if self.try_consume_byte(b'}') {
1949 return Ok(BorrowedJsonValue::Object(entries));
1950 }
1951 loop {
1952 if self.peek_byte() != Some(b'"') {
1953 return match self.peek_byte() {
1954 Some(found) => Err(JsonParseError::UnexpectedCharacter {
1955 index: self.index,
1956 found: found as char,
1957 }),
1958 None => Err(JsonParseError::UnexpectedEnd),
1959 };
1960 }
1961 let key = self.parse_string_borrowed()?;
1962 self.skip_whitespace();
1963 if !self.try_consume_byte(b':') {
1964 return Err(JsonParseError::ExpectedColon { index: self.index });
1965 }
1966 let value = self.parse_value_borrowed()?;
1967 entries.push((key, value));
1968 self.skip_whitespace();
1969 if self.try_consume_byte(b'}') {
1970 break;
1971 }
1972 if !self.try_consume_byte(b',') {
1973 return Err(JsonParseError::ExpectedCommaOrEnd {
1974 index: self.index,
1975 context: "object",
1976 });
1977 }
1978 self.skip_whitespace();
1979 }
1980 Ok(BorrowedJsonValue::Object(entries))
1981 }
1982
1983 fn parse_tape_object(
1984 &mut self,
1985 tokens: &mut Vec<TapeToken>,
1986 parent: Option<usize>,
1987 ) -> Result<usize, JsonParseError> {
1988 let start = self.index;
1989 self.consume_byte(b'{')?;
1990 let token_index = tokens.len();
1991 tokens.push(TapeToken {
1992 kind: TapeTokenKind::Object,
1993 start,
1994 end: start,
1995 parent,
1996 });
1997 self.skip_whitespace();
1998 if self.try_consume_byte(b'}') {
1999 tokens[token_index].end = self.index;
2000 return Ok(token_index);
2001 }
2002 loop {
2003 if self.peek_byte() != Some(b'"') {
2004 return match self.peek_byte() {
2005 Some(found) => Err(JsonParseError::UnexpectedCharacter {
2006 index: self.index,
2007 found: found as char,
2008 }),
2009 None => Err(JsonParseError::UnexpectedEnd),
2010 };
2011 }
2012 self.parse_tape_string(tokens, Some(token_index), TapeTokenKind::Key)?;
2013 self.skip_whitespace();
2014 if !self.try_consume_byte(b':') {
2015 return Err(JsonParseError::ExpectedColon { index: self.index });
2016 }
2017 self.parse_tape_value(tokens, Some(token_index))?;
2018 self.skip_whitespace();
2019 if self.try_consume_byte(b'}') {
2020 tokens[token_index].end = self.index;
2021 break;
2022 }
2023 if !self.try_consume_byte(b',') {
2024 return Err(JsonParseError::ExpectedCommaOrEnd {
2025 index: self.index,
2026 context: "object",
2027 });
2028 }
2029 self.skip_whitespace();
2030 }
2031 Ok(token_index)
2032 }
2033
2034 fn parse_string(&mut self) -> Result<String, JsonParseError> {
2035 self.consume_byte(b'"')?;
2036 let start = self.index;
2037 loop {
2038 let Some(byte) = self.next_byte() else {
2039 return Err(JsonParseError::UnexpectedEnd);
2040 };
2041 match byte {
2042 b'"' => {
2043 let slice = &self.input[start..self.index - 1];
2044 return Ok(slice.to_owned());
2045 }
2046 b'\\' => {
2047 let mut out = String::with_capacity(self.index - start + 8);
2048 out.push_str(&self.input[start..self.index - 1]);
2049 self.parse_escape_into(&mut out, self.index - 1)?;
2050 return self.parse_string_slow(out);
2051 }
2052 0x00..=0x1f => {
2053 return Err(JsonParseError::UnexpectedCharacter {
2054 index: self.index - 1,
2055 found: byte as char,
2056 })
2057 }
2058 _ => {}
2059 }
2060 }
2061 }
2062
2063 fn parse_string_borrowed(&mut self) -> Result<Cow<'a, str>, JsonParseError> {
2064 self.consume_byte(b'"')?;
2065 let start = self.index;
2066 loop {
2067 let Some(byte) = self.next_byte() else {
2068 return Err(JsonParseError::UnexpectedEnd);
2069 };
2070 match byte {
2071 b'"' => {
2072 let slice = &self.input[start..self.index - 1];
2073 return Ok(Cow::Borrowed(slice));
2074 }
2075 b'\\' => {
2076 let mut out = String::with_capacity(self.index - start + 8);
2077 out.push_str(&self.input[start..self.index - 1]);
2078 self.parse_escape_into(&mut out, self.index - 1)?;
2079 return self.parse_string_slow_borrowed(out);
2080 }
2081 0x00..=0x1f => {
2082 return Err(JsonParseError::UnexpectedCharacter {
2083 index: self.index - 1,
2084 found: byte as char,
2085 })
2086 }
2087 _ => {}
2088 }
2089 }
2090 }
2091
2092 fn parse_tape_string(
2093 &mut self,
2094 tokens: &mut Vec<TapeToken>,
2095 parent: Option<usize>,
2096 kind: TapeTokenKind,
2097 ) -> Result<usize, JsonParseError> {
2098 let start = self.index;
2099 self.skip_string_bytes()?;
2100 let token_index = tokens.len();
2101 tokens.push(TapeToken {
2102 kind,
2103 start,
2104 end: self.index,
2105 parent,
2106 });
2107 Ok(token_index)
2108 }
2109
2110 fn skip_string_bytes(&mut self) -> Result<(), JsonParseError> {
2111 self.consume_byte(b'"')?;
2112 loop {
2113 let Some(byte) = self.next_byte() else {
2114 return Err(JsonParseError::UnexpectedEnd);
2115 };
2116 match byte {
2117 b'"' => return Ok(()),
2118 b'\\' => {
2119 let escape_index = self.index - 1;
2120 let escaped = self.next_byte().ok_or(JsonParseError::UnexpectedEnd)?;
2121 match escaped {
2122 b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {}
2123 b'u' => {
2124 let scalar = self.parse_hex_quad(escape_index)?;
2125 if (0xD800..=0xDBFF).contains(&scalar) {
2126 if self.next_byte() != Some(b'\\') || self.next_byte() != Some(b'u')
2127 {
2128 return Err(JsonParseError::InvalidUnicodeScalar {
2129 index: escape_index,
2130 });
2131 }
2132 let low = self.parse_hex_quad(escape_index)?;
2133 if !(0xDC00..=0xDFFF).contains(&low) {
2134 return Err(JsonParseError::InvalidUnicodeScalar {
2135 index: escape_index,
2136 });
2137 }
2138 } else if (0xDC00..=0xDFFF).contains(&scalar) {
2139 return Err(JsonParseError::InvalidUnicodeScalar {
2140 index: escape_index,
2141 });
2142 }
2143 }
2144 _ => {
2145 return Err(JsonParseError::InvalidEscape {
2146 index: escape_index,
2147 })
2148 }
2149 }
2150 }
2151 0x00..=0x1f => {
2152 return Err(JsonParseError::UnexpectedCharacter {
2153 index: self.index - 1,
2154 found: byte as char,
2155 })
2156 }
2157 _ => {}
2158 }
2159 }
2160 }
2161
2162 fn parse_string_slow(&mut self, mut out: String) -> Result<String, JsonParseError> {
2163 let mut chunk_start = self.index;
2164 loop {
2165 let Some(byte) = self.next_byte() else {
2166 return Err(JsonParseError::UnexpectedEnd);
2167 };
2168 match byte {
2169 b'"' => {
2170 if chunk_start < self.index - 1 {
2171 out.push_str(&self.input[chunk_start..self.index - 1]);
2172 }
2173 return Ok(out);
2174 }
2175 b'\\' => {
2176 if chunk_start < self.index - 1 {
2177 out.push_str(&self.input[chunk_start..self.index - 1]);
2178 }
2179 self.parse_escape_into(&mut out, self.index - 1)?;
2180 chunk_start = self.index;
2181 }
2182 0x00..=0x1f => {
2183 return Err(JsonParseError::UnexpectedCharacter {
2184 index: self.index - 1,
2185 found: byte as char,
2186 })
2187 }
2188 _ => {}
2189 }
2190 }
2191 }
2192
2193 fn parse_string_slow_borrowed(
2194 &mut self,
2195 mut out: String,
2196 ) -> Result<Cow<'a, str>, JsonParseError> {
2197 let mut chunk_start = self.index;
2198 loop {
2199 let Some(byte) = self.next_byte() else {
2200 return Err(JsonParseError::UnexpectedEnd);
2201 };
2202 match byte {
2203 b'"' => {
2204 if chunk_start < self.index - 1 {
2205 out.push_str(&self.input[chunk_start..self.index - 1]);
2206 }
2207 return Ok(Cow::Owned(out));
2208 }
2209 b'\\' => {
2210 if chunk_start < self.index - 1 {
2211 out.push_str(&self.input[chunk_start..self.index - 1]);
2212 }
2213 self.parse_escape_into(&mut out, self.index - 1)?;
2214 chunk_start = self.index;
2215 }
2216 0x00..=0x1f => {
2217 return Err(JsonParseError::UnexpectedCharacter {
2218 index: self.index - 1,
2219 found: byte as char,
2220 })
2221 }
2222 _ => {}
2223 }
2224 }
2225 }
2226
2227 fn parse_escape_into(
2228 &mut self,
2229 out: &mut String,
2230 escape_index: usize,
2231 ) -> Result<(), JsonParseError> {
2232 let escaped = self.next_byte().ok_or(JsonParseError::UnexpectedEnd)?;
2233 match escaped {
2234 b'"' => out.push('"'),
2235 b'\\' => out.push('\\'),
2236 b'/' => out.push('/'),
2237 b'b' => out.push('\u{0008}'),
2238 b'f' => out.push('\u{000C}'),
2239 b'n' => out.push('\n'),
2240 b'r' => out.push('\r'),
2241 b't' => out.push('\t'),
2242 b'u' => out.push(self.parse_unicode_escape(escape_index)?),
2243 _ => {
2244 return Err(JsonParseError::InvalidEscape {
2245 index: escape_index,
2246 })
2247 }
2248 }
2249 Ok(())
2250 }
2251
2252 fn parse_unicode_escape(&mut self, index: usize) -> Result<char, JsonParseError> {
2253 let scalar = self.parse_hex_quad(index)?;
2254 if (0xD800..=0xDBFF).contains(&scalar) {
2255 if self.next_byte() != Some(b'\\') || self.next_byte() != Some(b'u') {
2256 return Err(JsonParseError::InvalidUnicodeScalar { index });
2257 }
2258 let low = self.parse_hex_quad(index)?;
2259 if !(0xDC00..=0xDFFF).contains(&low) {
2260 return Err(JsonParseError::InvalidUnicodeScalar { index });
2261 }
2262 let high = scalar - 0xD800;
2263 let low = low - 0xDC00;
2264 let combined = 0x10000 + ((high << 10) | low);
2265 char::from_u32(combined).ok_or(JsonParseError::InvalidUnicodeScalar { index })
2266 } else if (0xDC00..=0xDFFF).contains(&scalar) {
2267 Err(JsonParseError::InvalidUnicodeScalar { index })
2268 } else {
2269 char::from_u32(scalar).ok_or(JsonParseError::InvalidUnicodeScalar { index })
2270 }
2271 }
2272
2273 fn parse_hex_quad(&mut self, index: usize) -> Result<u32, JsonParseError> {
2274 let mut value = 0u32;
2275 for _ in 0..4 {
2276 let ch = self.next_byte().ok_or(JsonParseError::UnexpectedEnd)?;
2277 let digit = match ch {
2278 b'0'..=b'9' => (ch - b'0') as u32,
2279 b'a'..=b'f' => 10 + (ch - b'a') as u32,
2280 b'A'..=b'F' => 10 + (ch - b'A') as u32,
2281 _ => return Err(JsonParseError::InvalidUnicodeEscape { index }),
2282 };
2283 value = (value << 4) | digit;
2284 }
2285 Ok(value)
2286 }
2287
2288 fn parse_number(&mut self) -> Result<JsonNumber, JsonParseError> {
2289 let start = self.index;
2290 self.try_consume_byte(b'-');
2291 if self.try_consume_byte(b'0') {
2292 if matches!(self.peek_byte(), Some(b'0'..=b'9')) {
2293 return Err(JsonParseError::InvalidNumber { index: start });
2294 }
2295 } else {
2296 self.consume_digits(start)?;
2297 }
2298
2299 let mut is_float = false;
2300 if self.try_consume_byte(b'.') {
2301 is_float = true;
2302 self.consume_digits(start)?;
2303 }
2304 if matches!(self.peek_byte(), Some(b'e' | b'E')) {
2305 is_float = true;
2306 self.index += 1;
2307 if matches!(self.peek_byte(), Some(b'+' | b'-')) {
2308 self.index += 1;
2309 }
2310 self.consume_digits(start)?;
2311 }
2312
2313 let token = &self.input[start..self.index];
2314 if is_float {
2315 let value = token
2316 .parse::<f64>()
2317 .map_err(|_| JsonParseError::InvalidNumber { index: start })?;
2318 if !value.is_finite() {
2319 return Err(JsonParseError::InvalidNumber { index: start });
2320 }
2321 Ok(JsonNumber::F64(value))
2322 } else if token.starts_with('-') {
2323 let value = token
2324 .parse::<i64>()
2325 .map_err(|_| JsonParseError::InvalidNumber { index: start })?;
2326 Ok(JsonNumber::I64(value))
2327 } else {
2328 let value = token
2329 .parse::<u64>()
2330 .map_err(|_| JsonParseError::InvalidNumber { index: start })?;
2331 Ok(JsonNumber::U64(value))
2332 }
2333 }
2334
2335 fn parse_tape_number(
2336 &mut self,
2337 tokens: &mut Vec<TapeToken>,
2338 parent: Option<usize>,
2339 ) -> Result<usize, JsonParseError> {
2340 let start = self.index;
2341 let _ = self.parse_number()?;
2342 let token_index = tokens.len();
2343 tokens.push(TapeToken {
2344 kind: TapeTokenKind::Number,
2345 start,
2346 end: self.index,
2347 parent,
2348 });
2349 Ok(token_index)
2350 }
2351
2352 fn consume_digits(&mut self, index: usize) -> Result<(), JsonParseError> {
2353 let start = self.index;
2354 while matches!(self.peek_byte(), Some(b'0'..=b'9')) {
2355 self.index += 1;
2356 }
2357 if self.index == start {
2358 return Err(JsonParseError::InvalidNumber { index });
2359 }
2360 Ok(())
2361 }
2362
2363 fn consume_byte(&mut self, expected: u8) -> Result<(), JsonParseError> {
2364 match self.next_byte() {
2365 Some(found) if found == expected => Ok(()),
2366 Some(found) => Err(JsonParseError::UnexpectedCharacter {
2367 index: self.index.saturating_sub(1),
2368 found: found as char,
2369 }),
2370 None => Err(JsonParseError::UnexpectedEnd),
2371 }
2372 }
2373
2374 fn try_consume_byte(&mut self, expected: u8) -> bool {
2375 if self.peek_byte() == Some(expected) {
2376 self.index += 1;
2377 true
2378 } else {
2379 false
2380 }
2381 }
2382
2383 fn skip_whitespace(&mut self) {
2384 while matches!(self.peek_byte(), Some(b' ' | b'\n' | b'\r' | b'\t')) {
2385 self.index += 1;
2386 }
2387 }
2388
2389 fn peek_byte(&self) -> Option<u8> {
2390 self.bytes.get(self.index).copied()
2391 }
2392
2393 fn next_byte(&mut self) -> Option<u8> {
2394 let byte = self.peek_byte()?;
2395 self.index += 1;
2396 Some(byte)
2397 }
2398
2399 fn is_eof(&self) -> bool {
2400 self.index >= self.input.len()
2401 }
2402}
2403
2404#[cfg(test)]
2405mod tests {
2406 use super::*;
2407
2408 #[test]
2409 fn escapes_control_characters_and_quotes() {
2410 let escaped = escape_json_string("hello\t\"world\"\n\u{0007}");
2411 assert_eq!(escaped, "\"hello\\t\\\"world\\\"\\n\\u0007\"");
2412 }
2413
2414 #[test]
2415 fn serializes_nested_values() {
2416 let value = JsonValue::object(vec![
2417 ("name", "node-1".into()),
2418 ("ok", true.into()),
2419 (
2420 "values",
2421 JsonValue::array(vec![1u32.into(), 2u32.into(), JsonValue::Null]),
2422 ),
2423 ]);
2424 assert_eq!(
2425 value.to_json_string().unwrap(),
2426 "{\"name\":\"node-1\",\"ok\":true,\"values\":[1,2,null]}"
2427 );
2428 }
2429
2430 #[test]
2431 fn rejects_non_finite_float() {
2432 let value = JsonValue::from(f64::NAN);
2433 assert_eq!(value.to_json_string(), Err(JsonError::NonFiniteNumber));
2434 }
2435
2436 #[test]
2437 fn parses_basic_json_values() {
2438 assert_eq!(parse_json("null").unwrap(), JsonValue::Null);
2439 assert_eq!(parse_json("true").unwrap(), JsonValue::Bool(true));
2440 assert_eq!(
2441 parse_json("\"hello\"").unwrap(),
2442 JsonValue::String("hello".into())
2443 );
2444 assert_eq!(
2445 parse_json("123").unwrap(),
2446 JsonValue::Number(JsonNumber::U64(123))
2447 );
2448 assert_eq!(
2449 parse_json("-123").unwrap(),
2450 JsonValue::Number(JsonNumber::I64(-123))
2451 );
2452 }
2453
2454 #[test]
2455 fn parses_unicode_and_escapes() {
2456 let value = parse_json("\"line\\n\\u03bb\\uD83D\\uDE80\"").unwrap();
2457 assert_eq!(value, JsonValue::String("line\nλ🚀".into()));
2458 }
2459
2460 #[test]
2461 fn borrowed_parse_avoids_allocating_plain_strings() {
2462 let value = parse_json_borrowed("{\"name\":\"hello\",\"n\":1}").unwrap();
2463 match value {
2464 BorrowedJsonValue::Object(entries) => {
2465 assert!(matches!(entries[0].0, Cow::Borrowed(_)));
2466 assert!(matches!(
2467 entries[0].1,
2468 BorrowedJsonValue::String(Cow::Borrowed(_))
2469 ));
2470 }
2471 other => panic!("unexpected value: {other:?}"),
2472 }
2473 }
2474
2475 #[test]
2476 fn borrowed_parse_allocates_when_unescaping_is_needed() {
2477 let value = parse_json_borrowed("\"line\\nvalue\"").unwrap();
2478 match value {
2479 BorrowedJsonValue::String(Cow::Owned(text)) => assert_eq!(text, "line\nvalue"),
2480 other => panic!("unexpected value: {other:?}"),
2481 }
2482 }
2483
2484 #[test]
2485 fn compiled_schema_serializes_expected_shape() {
2486 let schema = CompiledObjectSchema::new(&["id", "name", "enabled"]);
2487 let values = [
2488 JsonValue::from(7u64),
2489 JsonValue::from("node-7"),
2490 JsonValue::from(true),
2491 ];
2492 let json = schema.to_json_string(values.iter()).unwrap();
2493 assert_eq!(json, "{\"id\":7,\"name\":\"node-7\",\"enabled\":true}");
2494 }
2495
2496 #[test]
2497 fn compiled_row_schema_serializes_array_of_objects() {
2498 let schema = CompiledRowSchema::new(&["id", "name"]);
2499 let row1 = [JsonValue::from(1u64), JsonValue::from("a")];
2500 let row2 = [JsonValue::from(2u64), JsonValue::from("b")];
2501 let json = schema.to_json_string([row1.iter(), row2.iter()]).unwrap();
2502 assert_eq!(json, r#"[{"id":1,"name":"a"},{"id":2,"name":"b"}]"#);
2503 }
2504
2505 #[test]
2506 fn tape_parse_records_structure_tokens() {
2507 let tape = parse_json_tape(r#"{"a":[1,"x"],"b":true}"#).unwrap();
2508 assert_eq!(tape.tokens[0].kind, TapeTokenKind::Object);
2509 assert_eq!(tape.tokens[1].kind, TapeTokenKind::Key);
2510 assert_eq!(tape.tokens[2].kind, TapeTokenKind::Array);
2511 assert_eq!(tape.tokens[3].kind, TapeTokenKind::Number);
2512 assert_eq!(tape.tokens[4].kind, TapeTokenKind::String);
2513 assert_eq!(tape.tokens[5].kind, TapeTokenKind::Key);
2514 assert_eq!(tape.tokens[6].kind, TapeTokenKind::Bool);
2515 }
2516
2517 #[test]
2518 fn tape_object_lookup_finds_child_values() {
2519 let input = r#"{"name":"hello","nested":{"x":1},"flag":true}"#;
2520 let tape = parse_json_tape(input).unwrap();
2521 let root = tape.root(input).unwrap();
2522 let name = root.get("name").unwrap();
2523 assert_eq!(name.kind(), TapeTokenKind::String);
2524 assert_eq!(name.as_str(), Some("hello"));
2525 let nested = root.get("nested").unwrap();
2526 assert_eq!(nested.kind(), TapeTokenKind::Object);
2527 assert!(root.get("missing").is_none());
2528 }
2529
2530 #[test]
2531 fn tape_object_index_lookup_finds_child_values() {
2532 let input = r#"{"name":"hello","nested":{"x":1},"flag":true}"#;
2533 let tape = parse_json_tape(input).unwrap();
2534 let root = tape.root(input).unwrap();
2535 let index = root.build_object_index().unwrap();
2536 let flag = index.get(root, "flag").unwrap();
2537 assert_eq!(flag.kind(), TapeTokenKind::Bool);
2538 assert!(index.get(root, "missing").is_none());
2539 }
2540
2541 #[test]
2542 fn indexed_tape_object_compiled_lookup_finds_child_values() {
2543 let input = r#"{"name":"hello","nested":{"x":1},"flag":true}"#;
2544 let tape = parse_json_tape(input).unwrap();
2545 let root = tape.root(input).unwrap();
2546 let index = root.build_object_index().unwrap();
2547 let indexed = root.with_index(&index);
2548 let keys = CompiledTapeKeys::new(&["name", "flag", "missing"]);
2549 let got = indexed
2550 .get_compiled_many(&keys)
2551 .map(|value| value.map(|value| value.kind()))
2552 .collect::<Vec<_>>();
2553 assert_eq!(got, vec![Some(TapeTokenKind::String), Some(TapeTokenKind::Bool), None]);
2554 }
2555
2556 #[test]
2557 fn serde_style_convenience_api_works() {
2558 let value = from_str(r#"{"ok":true,"n":7,"items":[1,2,3],"msg":"hello"}"#).unwrap();
2559 assert!(value.is_object());
2560 assert_eq!(value["ok"].as_bool(), Some(true));
2561 assert_eq!(value["n"].as_i64(), Some(7));
2562 assert_eq!(value["msg"].as_str(), Some("hello"));
2563 assert_eq!(value["items"][1].as_u64(), Some(2));
2564 assert!(value["missing"].is_null());
2565 assert_eq!(to_string(&value).unwrap(), r#"{"ok":true,"n":7,"items":[1,2,3],"msg":"hello"}"#);
2566 assert_eq!(from_slice(br#"[1,true,"x"]"#).unwrap()[2].as_str(), Some("x"));
2567 assert_eq!(to_vec(&value).unwrap(), value.to_json_string().unwrap().into_bytes());
2568 }
2569
2570 #[test]
2571 fn json_macro_builds_values() {
2572 let value = json!({"ok": true, "items": [1, 2, null], "msg": "x"});
2573 assert_eq!(value["ok"].as_bool(), Some(true));
2574 assert_eq!(value["items"][0].as_u64(), Some(1));
2575 assert!(value["items"][2].is_null());
2576 assert_eq!(value["msg"].as_str(), Some("x"));
2577 }
2578
2579 #[test]
2580 fn from_slice_rejects_invalid_utf8() {
2581 assert!(matches!(from_slice(&[0xff]), Err(JsonParseError::InvalidUtf8)));
2582 }
2583
2584 #[test]
2585 fn pointer_take_and_pretty_helpers_work() {
2586 let mut value = from_str(r#"{"a":{"b":[10,20,{"~key/":"x"}]}}"#).unwrap();
2587 assert_eq!(value.pointer("/a/b/1").and_then(JsonValue::as_u64), Some(20));
2588 assert_eq!(value.pointer("/a/b/2/~0key~1").and_then(JsonValue::as_str), Some("x"));
2589 *value.pointer_mut("/a/b/0").unwrap() = JsonValue::from(99u64);
2590 assert_eq!(value.pointer("/a/b/0").and_then(JsonValue::as_u64), Some(99));
2591
2592 let taken = value.pointer_mut("/a/b/2").unwrap().take();
2593 assert!(value.pointer("/a/b/2").unwrap().is_null());
2594 assert_eq!(taken["~key/"].as_str(), Some("x"));
2595
2596 let pretty = to_string_pretty(&value).unwrap();
2597 assert!(pretty.contains("\"a\": {"));
2598 let mut out = Vec::new();
2599 to_writer_pretty(&mut out, &value).unwrap();
2600 assert_eq!(String::from_utf8(out).unwrap(), pretty);
2601 }
2602
2603 #[test]
2604 fn reader_writer_and_collection_helpers_work() {
2605 let value = from_reader(std::io::Cursor::new(br#"{"a":1,"b":[true,false]}"# as &[u8])).unwrap();
2606 assert_eq!(value["a"].as_u64(), Some(1));
2607 assert_eq!(value["b"].len(), 2);
2608 assert_eq!(value["b"].get_index(1).and_then(JsonValue::as_bool), Some(false));
2609
2610 let mut out = Vec::new();
2611 to_writer(&mut out, &value).unwrap();
2612 assert_eq!(String::from_utf8(out).unwrap(), value.to_json_string().unwrap());
2613
2614 let object = JsonValue::from_iter([("x", 1u64), ("y", 2u64)]);
2615 assert_eq!(object["x"].as_u64(), Some(1));
2616 let array = JsonValue::from_iter([1u64, 2u64, 3u64]);
2617 assert_eq!(array.get_index(2).and_then(JsonValue::as_u64), Some(3));
2618 }
2619
2620 #[test]
2621 fn primitive_partial_eq_parity_works() {
2622 let value = json!({"n": 1, "f": 2.5, "b": true, "s": "x"});
2623 assert_eq!(value["n"], 1);
2624 assert_eq!(1, value["n"]);
2625 assert_eq!(value["f"], 2.5);
2626 assert_eq!(value["b"], true);
2627 assert_eq!(value["s"], "x");
2628 assert_eq!(String::from("x"), value["s"]);
2629 }
2630
2631 #[test]
2632 fn signature_and_sort_parity_helpers_work() {
2633 let mut value = json!({"z": {"b": 2, "a": 1}, "a": [{"d": 4, "c": 3}]});
2634 assert_eq!(value.as_object().unwrap().len(), 2);
2635 assert_eq!(value["a"].as_array().unwrap().len(), 1);
2636 value.sort_all_objects();
2637 let root_keys = value.as_object().unwrap().iter().map(|(k, _)| k.as_str()).collect::<Vec<_>>();
2638 assert_eq!(root_keys, vec!["a", "z"]);
2639 let nested_keys = value["z"].as_object().unwrap().iter().map(|(k, _)| k.as_str()).collect::<Vec<_>>();
2640 assert_eq!(nested_keys, vec!["a", "b"]);
2641 }
2642
2643 #[test]
2644 fn generic_get_and_get_mut_index_parity_work() {
2645 let mut value = json!({"obj": {"x": 1}, "arr": [10, 20, 30]});
2646 let key = String::from("obj");
2647 assert_eq!(value.get("obj").and_then(|v| v.get("x")).and_then(JsonValue::as_u64), Some(1));
2648 assert_eq!(value.get(&key).and_then(|v| v.get("x")).and_then(JsonValue::as_u64), Some(1));
2649 assert_eq!(value.get("arr").and_then(|v| v.get(1)).and_then(JsonValue::as_u64), Some(20));
2650 *value.get_mut("arr").unwrap().get_mut(2).unwrap() = JsonValue::from(99u64);
2651 assert_eq!(value["arr"][2].as_u64(), Some(99));
2652 }
2653
2654 #[test]
2655 fn number_and_mut_index_parity_helpers_work() {
2656 let int = JsonValue::from(7i64);
2657 assert!(int.is_i64());
2658 assert!(!int.is_u64());
2659 assert!(!int.is_f64());
2660 assert_eq!(int.as_number().and_then(JsonNumber::as_i64), Some(7));
2661
2662 let float = JsonValue::Number(JsonNumber::from_f64(2.5).unwrap());
2663 assert!(float.is_f64());
2664 assert_eq!(float.as_f64(), Some(2.5));
2665 assert_eq!(JsonValue::Null.as_null(), Some(()));
2666
2667 let mut value = JsonValue::Null;
2668 value["a"]["b"]["c"] = JsonValue::from(true);
2669 assert_eq!(value.pointer("/a/b/c").and_then(JsonValue::as_bool), Some(true));
2670
2671 value["arr"] = json!([1, 2, 3]);
2672 value["arr"][1] = JsonValue::from(9u64);
2673 assert_eq!(value.pointer("/arr/1").and_then(JsonValue::as_u64), Some(9));
2674 }
2675
2676 #[test]
2677 fn rejects_invalid_json_inputs() {
2678 assert!(matches!(
2679 parse_json("{"),
2680 Err(JsonParseError::UnexpectedEnd)
2681 ));
2682 assert!(matches!(
2683 parse_json("{\"a\" 1}"),
2684 Err(JsonParseError::ExpectedColon { .. })
2685 ));
2686 assert!(matches!(
2687 parse_json("[1 2]"),
2688 Err(JsonParseError::ExpectedCommaOrEnd {
2689 context: "array",
2690 ..
2691 })
2692 ));
2693 assert!(matches!(
2694 parse_json("{\"a\":1 trailing"),
2695 Err(JsonParseError::ExpectedCommaOrEnd {
2696 context: "object",
2697 ..
2698 })
2699 ));
2700 assert!(matches!(
2701 parse_json("00"),
2702 Err(JsonParseError::InvalidNumber { .. })
2703 ));
2704 }
2705
2706 #[test]
2707 fn roundtrips_specific_structures() {
2708 let values = [
2709 JsonValue::Null,
2710 JsonValue::Bool(false),
2711 JsonValue::String("tab\tquote\"slash\\snowman☃".into()),
2712 JsonValue::Number(JsonNumber::I64(-9_223_372_036_854_775_808)),
2713 JsonValue::Number(JsonNumber::U64(u64::MAX)),
2714 JsonValue::Number(JsonNumber::F64(12345.125)),
2715 JsonValue::Array(vec![
2716 JsonValue::Bool(true),
2717 JsonValue::String("nested".into()),
2718 JsonValue::Object(vec![("x".into(), 1u64.into())]),
2719 ]),
2720 ];
2721 for value in values {
2722 let text = value.to_json_string().unwrap();
2723 let reparsed = parse_json(&text).unwrap();
2724 assert_json_equivalent(&value, &reparsed);
2725 }
2726 }
2727
2728 #[test]
2729 fn deterministic_fuzz_roundtrip_strings_and_values() {
2730 let mut rng = Rng::new(0x5eed_1234_5678_9abc);
2731 for _ in 0..2_000 {
2732 let input = random_string(&mut rng, 48);
2733 let escaped = escape_json_string(&input);
2734 let parsed = parse_json(&escaped).unwrap();
2735 assert_eq!(parsed, JsonValue::String(input));
2736 }
2737
2738 for _ in 0..1_000 {
2739 let value = random_json_value(&mut rng, 0, 4);
2740 let text = value.to_json_string().unwrap();
2741 let reparsed = parse_json(&text).unwrap();
2742 assert_json_equivalent(&value, &reparsed);
2743 }
2744 }
2745
2746 fn assert_json_equivalent(expected: &JsonValue, actual: &JsonValue) {
2747 match (expected, actual) {
2748 (JsonValue::Null, JsonValue::Null) => {}
2749 (JsonValue::Bool(a), JsonValue::Bool(b)) => assert_eq!(a, b),
2750 (JsonValue::String(a), JsonValue::String(b)) => assert_eq!(a, b),
2751 (JsonValue::Number(a), JsonValue::Number(b)) => assert_numbers_equivalent(a, b),
2752 (JsonValue::Array(a), JsonValue::Array(b)) => {
2753 assert_eq!(a.len(), b.len());
2754 for (left, right) in a.iter().zip(b.iter()) {
2755 assert_json_equivalent(left, right);
2756 }
2757 }
2758 (JsonValue::Object(a), JsonValue::Object(b)) => {
2759 assert_eq!(a.len(), b.len());
2760 for ((left_key, left_value), (right_key, right_value)) in a.iter().zip(b.iter()) {
2761 assert_eq!(left_key, right_key);
2762 assert_json_equivalent(left_value, right_value);
2763 }
2764 }
2765 _ => panic!("json values differ: expected {expected:?}, actual {actual:?}"),
2766 }
2767 }
2768
2769 fn assert_numbers_equivalent(expected: &JsonNumber, actual: &JsonNumber) {
2770 match (expected, actual) {
2771 (JsonNumber::I64(a), JsonNumber::I64(b)) => assert_eq!(a, b),
2772 (JsonNumber::U64(a), JsonNumber::U64(b)) => assert_eq!(a, b),
2773 (JsonNumber::F64(a), JsonNumber::F64(b)) => assert_eq!(a.to_bits(), b.to_bits()),
2774 (JsonNumber::I64(a), JsonNumber::U64(b)) if *a >= 0 => assert_eq!(*a as u64, *b),
2775 (JsonNumber::U64(a), JsonNumber::I64(b)) if *b >= 0 => assert_eq!(*a, *b as u64),
2776 (JsonNumber::I64(a), JsonNumber::F64(b)) => assert_eq!(*a as f64, *b),
2777 (JsonNumber::U64(a), JsonNumber::F64(b)) => assert_eq!(*a as f64, *b),
2778 (JsonNumber::F64(a), JsonNumber::I64(b)) => assert_eq!(*a, *b as f64),
2779 (JsonNumber::F64(a), JsonNumber::U64(b)) => assert_eq!(*a, *b as f64),
2780 (left, right) => panic!("json numbers differ: expected {left:?}, actual {right:?}"),
2781 }
2782 }
2783
2784 #[derive(Clone, Debug)]
2785 struct Rng {
2786 state: u64,
2787 }
2788
2789 impl Rng {
2790 fn new(seed: u64) -> Self {
2791 Self { state: seed }
2792 }
2793
2794 fn next_u64(&mut self) -> u64 {
2795 self.state = self
2796 .state
2797 .wrapping_mul(6364136223846793005)
2798 .wrapping_add(1442695040888963407);
2799 self.state
2800 }
2801
2802 fn choose(&mut self, upper_exclusive: usize) -> usize {
2803 (self.next_u64() % upper_exclusive as u64) as usize
2804 }
2805
2806 fn bool(&mut self) -> bool {
2807 (self.next_u64() & 1) == 1
2808 }
2809 }
2810
2811 fn random_string(rng: &mut Rng, max_len: usize) -> String {
2812 let len = rng.choose(max_len + 1);
2813 let mut out = String::new();
2814 for _ in 0..len {
2815 let ch = match rng.choose(12) {
2816 0 => '"',
2817 1 => '\\',
2818 2 => '\n',
2819 3 => '\r',
2820 4 => '\t',
2821 5 => '\u{0007}',
2822 6 => 'λ',
2823 7 => '🚀',
2824 8 => '☃',
2825 _ => (b'a' + rng.choose(26) as u8) as char,
2826 };
2827 out.push(ch);
2828 }
2829 out
2830 }
2831
2832 fn random_json_value(rng: &mut Rng, depth: usize, max_depth: usize) -> JsonValue {
2833 if depth >= max_depth {
2834 return random_leaf(rng);
2835 }
2836 match rng.choose(7) {
2837 0 | 1 | 2 | 3 => random_leaf(rng),
2838 4 => {
2839 let len = rng.choose(5);
2840 let mut values = Vec::with_capacity(len);
2841 for _ in 0..len {
2842 values.push(random_json_value(rng, depth + 1, max_depth));
2843 }
2844 JsonValue::Array(values)
2845 }
2846 _ => {
2847 let len = rng.choose(5);
2848 let mut entries = Vec::with_capacity(len);
2849 for index in 0..len {
2850 entries.push((
2851 format!("k{depth}_{index}_{}", random_string(rng, 6)),
2852 random_json_value(rng, depth + 1, max_depth),
2853 ));
2854 }
2855 JsonValue::Object(entries)
2856 }
2857 }
2858 }
2859
2860 fn random_leaf(rng: &mut Rng) -> JsonValue {
2861 match rng.choose(6) {
2862 0 => JsonValue::Null,
2863 1 => JsonValue::Bool(rng.bool()),
2864 2 => JsonValue::String(random_string(rng, 24)),
2865 3 => JsonValue::Number(JsonNumber::I64(
2866 (rng.next_u64() >> 1) as i64 * if rng.bool() { 1 } else { -1 },
2867 )),
2868 4 => JsonValue::Number(JsonNumber::U64(rng.next_u64())),
2869 _ => {
2870 let mantissa = (rng.next_u64() % 1_000_000) as f64 / 1000.0;
2871 let sign = if rng.bool() { 1.0 } else { -1.0 };
2872 JsonValue::Number(JsonNumber::F64(sign * mantissa))
2873 }
2874 }
2875 }
2876}