Skip to main content

lifegraph_json/
lib.rs

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}