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<&[JsonValue]> {
323        match self {
324            Self::Array(values) => Some(values.as_slice()),
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<&[(String, JsonValue)]> {
337        match self {
338            Self::Object(entries) => Some(entries.as_slice()),
339            _ => None,
340        }
341    }
342
343    pub fn as_object_mut(&mut self) -> Option<&mut Vec<(String, JsonValue)>> {
344        match self {
345            Self::Object(entries) => Some(entries),
346            _ => None,
347        }
348    }
349
350    pub fn get(&self, key: &str) -> Option<&JsonValue> {
351        match self {
352            Self::Object(entries) => object_get(entries, key),
353            _ => None,
354        }
355    }
356
357    pub fn get_mut(&mut self, key: &str) -> Option<&mut JsonValue> {
358        match self {
359            Self::Object(entries) => object_get_mut(entries, key),
360            _ => None,
361        }
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
451impl<'a> BorrowedJsonValue<'a> {
452    pub fn into_owned(self) -> JsonValue {
453        match self {
454            Self::Null => JsonValue::Null,
455            Self::Bool(value) => JsonValue::Bool(value),
456            Self::Number(value) => JsonValue::Number(value),
457            Self::String(value) => JsonValue::String(value.into_owned()),
458            Self::Array(values) => JsonValue::Array(
459                values
460                    .into_iter()
461                    .map(BorrowedJsonValue::into_owned)
462                    .collect(),
463            ),
464            Self::Object(entries) => JsonValue::Object(
465                entries
466                    .into_iter()
467                    .map(|(key, value)| (key.into_owned(), value.into_owned()))
468                    .collect(),
469            ),
470        }
471    }
472}
473
474impl CompiledObjectSchema {
475    pub fn new(keys: &[&str]) -> Self {
476        let mut fields = Vec::with_capacity(keys.len());
477        let mut capacity_hint = 2;
478        for (index, key) in keys.iter().enumerate() {
479            let mut rendered_prefix = Vec::with_capacity(key.len() + 4);
480            if index > 0 {
481                rendered_prefix.push(b',');
482            }
483            write_json_key(&mut rendered_prefix, key);
484            capacity_hint += rendered_prefix.len() + 8;
485            fields.push(CompiledField {
486                key: (*key).to_owned(),
487                rendered_prefix,
488            });
489        }
490        Self {
491            fields,
492            capacity_hint,
493        }
494    }
495
496    pub fn keys(&self) -> impl ExactSizeIterator<Item = &str> {
497        self.fields.iter().map(|field| field.key.as_str())
498    }
499
500    pub fn to_json_string<'a, I>(&self, values: I) -> Result<String, JsonError>
501    where
502        I: IntoIterator<Item = &'a JsonValue>,
503    {
504        let mut out = Vec::with_capacity(self.capacity_hint);
505        self.write_json_bytes(&mut out, values)?;
506        Ok(unsafe { String::from_utf8_unchecked(out) })
507    }
508
509    pub fn write_json_bytes<'a, I>(&self, out: &mut Vec<u8>, values: I) -> Result<(), JsonError>
510    where
511        I: IntoIterator<Item = &'a JsonValue>,
512    {
513        out.push(b'{');
514        let mut iter = values.into_iter();
515        for field in &self.fields {
516            let Some(value) = iter.next() else {
517                panic!(
518                    "compiled object schema expected {} values",
519                    self.fields.len()
520                );
521            };
522            out.extend_from_slice(&field.rendered_prefix);
523            write_json_value(out, value)?;
524        }
525        if iter.next().is_some() {
526            panic!(
527                "compiled object schema received more than {} values",
528                self.fields.len()
529            );
530        }
531        out.push(b'}');
532        Ok(())
533    }
534}
535
536impl CompiledRowSchema {
537    pub fn new(keys: &[&str]) -> Self {
538        let object = CompiledObjectSchema::new(keys);
539        let row_capacity_hint = object.capacity_hint;
540        Self {
541            object,
542            row_capacity_hint,
543        }
544    }
545
546    pub fn object_schema(&self) -> &CompiledObjectSchema {
547        &self.object
548    }
549
550    pub fn to_json_string<'a, R, I>(&self, rows: R) -> Result<String, JsonError>
551    where
552        R: IntoIterator<Item = I>,
553        I: IntoIterator<Item = &'a JsonValue>,
554    {
555        let iter = rows.into_iter();
556        let (lower, _) = iter.size_hint();
557        let mut out = Vec::with_capacity(2 + lower.saturating_mul(self.row_capacity_hint + 1));
558        self.write_json_bytes_from_iter(&mut out, iter)?;
559        Ok(unsafe { String::from_utf8_unchecked(out) })
560    }
561
562    pub fn write_json_bytes<'a, R, I>(&self, out: &mut Vec<u8>, rows: R) -> Result<(), JsonError>
563    where
564        R: IntoIterator<Item = I>,
565        I: IntoIterator<Item = &'a JsonValue>,
566    {
567        self.write_json_bytes_from_iter(out, rows.into_iter())
568    }
569
570    pub fn write_row_json_bytes<'a, I>(&self, out: &mut Vec<u8>, values: I) -> Result<(), JsonError>
571    where
572        I: IntoIterator<Item = &'a JsonValue>,
573    {
574        self.object.write_json_bytes(out, values)
575    }
576
577    fn write_json_bytes_from_iter<'a, R, I>(
578        &self,
579        out: &mut Vec<u8>,
580        mut rows: R,
581    ) -> Result<(), JsonError>
582    where
583        R: Iterator<Item = I>,
584        I: IntoIterator<Item = &'a JsonValue>,
585    {
586        out.push(b'[');
587        if let Some(first_row) = rows.next() {
588            self.object.write_json_bytes(out, first_row)?;
589            for row in rows {
590                out.push(b',');
591                self.object.write_json_bytes(out, row)?;
592            }
593        }
594        out.push(b']');
595        Ok(())
596    }
597}
598
599impl From<bool> for JsonValue {
600    fn from(value: bool) -> Self {
601        Self::Bool(value)
602    }
603}
604
605impl From<String> for JsonValue {
606    fn from(value: String) -> Self {
607        Self::String(value)
608    }
609}
610
611impl From<&str> for JsonValue {
612    fn from(value: &str) -> Self {
613        Self::String(value.to_owned())
614    }
615}
616
617impl From<i8> for JsonValue {
618    fn from(value: i8) -> Self {
619        Self::Number(JsonNumber::I64(value as i64))
620    }
621}
622
623impl From<i16> for JsonValue {
624    fn from(value: i16) -> Self {
625        Self::Number(JsonNumber::I64(value as i64))
626    }
627}
628
629impl From<i32> for JsonValue {
630    fn from(value: i32) -> Self {
631        Self::Number(JsonNumber::I64(value as i64))
632    }
633}
634
635impl From<i64> for JsonValue {
636    fn from(value: i64) -> Self {
637        Self::Number(JsonNumber::I64(value))
638    }
639}
640
641impl From<isize> for JsonValue {
642    fn from(value: isize) -> Self {
643        Self::Number(JsonNumber::I64(value as i64))
644    }
645}
646
647impl From<u8> for JsonValue {
648    fn from(value: u8) -> Self {
649        Self::Number(JsonNumber::U64(value as u64))
650    }
651}
652
653impl From<u16> for JsonValue {
654    fn from(value: u16) -> Self {
655        Self::Number(JsonNumber::U64(value as u64))
656    }
657}
658
659impl From<u32> for JsonValue {
660    fn from(value: u32) -> Self {
661        Self::Number(JsonNumber::U64(value as u64))
662    }
663}
664
665impl From<u64> for JsonValue {
666    fn from(value: u64) -> Self {
667        Self::Number(JsonNumber::U64(value))
668    }
669}
670
671impl From<usize> for JsonValue {
672    fn from(value: usize) -> Self {
673        Self::Number(JsonNumber::U64(value as u64))
674    }
675}
676
677impl From<f32> for JsonValue {
678    fn from(value: f32) -> Self {
679        Self::Number(JsonNumber::F64(value as f64))
680    }
681}
682
683impl From<f64> for JsonValue {
684    fn from(value: f64) -> Self {
685        Self::Number(JsonNumber::F64(value))
686    }
687}
688
689impl<T> From<Option<T>> for JsonValue
690where
691    T: Into<JsonValue>,
692{
693    fn from(value: Option<T>) -> Self {
694        match value {
695            Some(value) => value.into(),
696            None => Self::Null,
697        }
698    }
699}
700
701impl<T> From<Vec<T>> for JsonValue
702where
703    T: Into<JsonValue>,
704{
705    fn from(values: Vec<T>) -> Self {
706        Self::Array(values.into_iter().map(Into::into).collect())
707    }
708}
709
710
711impl<K, V> std::iter::FromIterator<(K, V)> for JsonValue
712where
713    K: Into<String>,
714    V: Into<JsonValue>,
715{
716    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
717        Self::Object(
718            iter.into_iter()
719                .map(|(key, value)| (key.into(), value.into()))
720                .collect(),
721        )
722    }
723}
724
725impl<T> std::iter::FromIterator<T> for JsonValue
726where
727    T: Into<JsonValue>,
728{
729    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
730        Self::Array(iter.into_iter().map(Into::into).collect())
731    }
732}
733
734pub fn escape_json_string(input: &str) -> String {
735    let mut out = Vec::with_capacity(input.len() + 2);
736    write_escaped_json_string(&mut out, input);
737    unsafe { String::from_utf8_unchecked(out) }
738}
739
740pub fn parse_json(input: &str) -> Result<JsonValue, JsonParseError> {
741    let mut parser = Parser::new(input);
742    let value = parser.parse_value()?;
743    parser.skip_whitespace();
744    if parser.is_eof() {
745        Ok(value)
746    } else {
747        Err(JsonParseError::UnexpectedTrailingCharacters(parser.index))
748    }
749}
750
751pub fn parse_json_borrowed(input: &str) -> Result<BorrowedJsonValue<'_>, JsonParseError> {
752    let mut parser = Parser::new(input);
753    let value = parser.parse_value_borrowed()?;
754    parser.skip_whitespace();
755    if parser.is_eof() {
756        Ok(value)
757    } else {
758        Err(JsonParseError::UnexpectedTrailingCharacters(parser.index))
759    }
760}
761
762pub fn parse_json_tape(input: &str) -> Result<JsonTape, JsonParseError> {
763    let mut parser = Parser::new(input);
764    let mut tokens = Vec::new();
765    parser.parse_tape_value(&mut tokens, None)?;
766    parser.skip_whitespace();
767    if parser.is_eof() {
768        Ok(JsonTape { tokens })
769    } else {
770        Err(JsonParseError::UnexpectedTrailingCharacters(parser.index))
771    }
772}
773
774
775pub fn from_str(input: &str) -> Result<JsonValue, JsonParseError> {
776    parse_json(input)
777}
778
779pub fn from_slice(input: &[u8]) -> Result<JsonValue, JsonParseError> {
780    let input = std::str::from_utf8(input).map_err(|_| JsonParseError::InvalidUtf8)?;
781    parse_json(input)
782}
783
784pub fn to_string(value: &JsonValue) -> Result<String, JsonError> {
785    value.to_json_string()
786}
787
788pub fn to_vec(value: &JsonValue) -> Result<Vec<u8>, JsonError> {
789    let mut out = Vec::with_capacity(initial_json_capacity(value));
790    write_json_value(&mut out, value)?;
791    Ok(out)
792}
793
794pub fn from_reader<R: Read>(mut reader: R) -> Result<JsonValue, JsonParseError> {
795    let mut input = String::new();
796    reader
797        .read_to_string(&mut input)
798        .map_err(|_| JsonParseError::InvalidUtf8)?;
799    parse_json(&input)
800}
801
802pub fn to_writer<W: Write>(mut writer: W, value: &JsonValue) -> Result<(), JsonError> {
803    let bytes = to_vec(value)?;
804    writer.write_all(&bytes).map_err(|_| JsonError::Io)
805}
806
807pub fn to_string_pretty(value: &JsonValue) -> Result<String, JsonError> {
808    let mut out = Vec::with_capacity(initial_json_capacity(value) + 16);
809    write_json_value_pretty(&mut out, value, 0)?;
810    Ok(unsafe { String::from_utf8_unchecked(out) })
811}
812
813pub fn to_vec_pretty(value: &JsonValue) -> Result<Vec<u8>, JsonError> {
814    let mut out = Vec::with_capacity(initial_json_capacity(value) + 16);
815    write_json_value_pretty(&mut out, value, 0)?;
816    Ok(out)
817}
818
819pub fn to_writer_pretty<W: Write>(mut writer: W, value: &JsonValue) -> Result<(), JsonError> {
820    let bytes = to_vec_pretty(value)?;
821    writer.write_all(&bytes).map_err(|_| JsonError::Io)
822}
823
824impl JsonTape {
825    pub fn root<'a>(&'a self, input: &'a str) -> Option<TapeValue<'a>> {
826        (!self.tokens.is_empty()).then_some(TapeValue {
827            tape: self,
828            input,
829            index: 0,
830        })
831    }
832}
833
834impl<'a> TapeValue<'a> {
835    pub fn kind(&self) -> TapeTokenKind {
836        self.tape.tokens[self.index].kind
837    }
838
839    pub fn as_str(&self) -> Option<&'a str> {
840        let token = &self.tape.tokens[self.index];
841        match token.kind {
842            TapeTokenKind::String | TapeTokenKind::Key => {
843                if self.input.as_bytes()[token.start] == b'"'
844                    && self.input.as_bytes()[token.end - 1] == b'"'
845                {
846                    Some(&self.input[token.start + 1..token.end - 1])
847                } else {
848                    None
849                }
850            }
851            _ => None,
852        }
853    }
854
855    pub fn get(&self, key: &str) -> Option<TapeValue<'a>> {
856        if self.kind() != TapeTokenKind::Object {
857            return None;
858        }
859        self.get_linear(key)
860    }
861
862    pub fn build_object_index(&self) -> Option<TapeObjectIndex> {
863        if self.kind() != TapeTokenKind::Object {
864            return None;
865        }
866        let parent = self.index;
867        let tokens = &self.tape.tokens;
868        let mut entries = Vec::new();
869        let mut i = self.index + 1;
870        while i + 1 < tokens.len() {
871            if tokens[i].parent != Some(parent) {
872                i += 1;
873                continue;
874            }
875            if tokens[i].kind == TapeTokenKind::Key && tokens[i + 1].parent == Some(parent) {
876                let candidate = TapeValue {
877                    tape: self.tape,
878                    input: self.input,
879                    index: i,
880                };
881                let key = candidate.as_str().unwrap_or("");
882                let hash = hash_key(key.as_bytes());
883                entries.push((hash, i, i + 1));
884                i += 2;
885            } else {
886                i += 1;
887            }
888        }
889        let bucket_count = (entries.len().next_power_of_two().max(1)) * 2;
890        let mut buckets = vec![Vec::new(); bucket_count];
891        for entry in entries {
892            let bucket = (entry.0 as usize) & (bucket_count - 1);
893            buckets[bucket].push(entry);
894        }
895        Some(TapeObjectIndex { buckets })
896    }
897
898    pub fn with_index<'b>(&'b self, index: &'b TapeObjectIndex) -> IndexedTapeObject<'b> {
899        IndexedTapeObject {
900            object: TapeValue {
901                tape: self.tape,
902                input: self.input,
903                index: self.index,
904            },
905            index,
906        }
907    }
908
909    fn get_linear(&self, key: &str) -> Option<TapeValue<'a>> {
910        let parent = self.index;
911        let tokens = &self.tape.tokens;
912        let mut i = self.index + 1;
913        while i < tokens.len() {
914            if tokens[i].parent != Some(parent) {
915                i += 1;
916                continue;
917            }
918            if tokens[i].kind != TapeTokenKind::Key {
919                i += 1;
920                continue;
921            }
922            let candidate = TapeValue {
923                tape: self.tape,
924                input: self.input,
925                index: i,
926            };
927            if candidate.as_str() == Some(key) {
928                let value_index = i + 1;
929                if value_index < tokens.len() && tokens[value_index].parent == Some(parent) {
930                    return Some(TapeValue {
931                        tape: self.tape,
932                        input: self.input,
933                        index: value_index,
934                    });
935                }
936                return None;
937            }
938            i += 1;
939        }
940        None
941    }
942}
943
944impl TapeObjectIndex {
945    pub fn get<'a>(&self, object: TapeValue<'a>, key: &str) -> Option<TapeValue<'a>> {
946        self.get_hashed(object, hash_key(key.as_bytes()), key)
947    }
948
949    pub fn get_compiled<'a>(&self, object: TapeValue<'a>, key: &CompiledTapeKey) -> Option<TapeValue<'a>> {
950        self.get_hashed(object, key.hash, &key.key)
951    }
952
953    fn get_hashed<'a>(&self, object: TapeValue<'a>, hash: u64, key: &str) -> Option<TapeValue<'a>> {
954        let bucket = (hash as usize) & (self.buckets.len() - 1);
955        for (entry_hash, key_index, value_index) in &self.buckets[bucket] {
956            if *entry_hash != hash {
957                continue;
958            }
959            let candidate = TapeValue {
960                tape: object.tape,
961                input: object.input,
962                index: *key_index,
963            };
964            if candidate.as_str() == Some(key) {
965                return Some(TapeValue {
966                    tape: object.tape,
967                    input: object.input,
968                    index: *value_index,
969                });
970            }
971        }
972        None
973    }
974}
975
976impl CompiledTapeKey {
977    pub fn new(key: impl Into<String>) -> Self {
978        let key = key.into();
979        let hash = hash_key(key.as_bytes());
980        Self { key, hash }
981    }
982
983    pub fn as_str(&self) -> &str {
984        &self.key
985    }
986}
987
988impl CompiledTapeKeys {
989    pub fn new(keys: &[&str]) -> Self {
990        Self {
991            keys: keys.iter().map(|key| CompiledTapeKey::new(*key)).collect(),
992        }
993    }
994
995    pub fn iter(&self) -> impl Iterator<Item = &CompiledTapeKey> {
996        self.keys.iter()
997    }
998}
999
1000impl<'a> IndexedTapeObject<'a> {
1001    pub fn get(&self, key: &str) -> Option<TapeValue<'a>> {
1002        self.index.get(self.object, key)
1003    }
1004
1005    pub fn get_compiled(&self, key: &CompiledTapeKey) -> Option<TapeValue<'a>> {
1006        self.index.get_compiled(self.object, key)
1007    }
1008
1009    pub fn get_many<'b>(
1010        &'b self,
1011        keys: &'b [&'b str],
1012    ) -> impl Iterator<Item = Option<TapeValue<'a>>> + 'b {
1013        keys.iter().map(|key| self.get(key))
1014    }
1015
1016    pub fn get_compiled_many<'b>(
1017        &'b self,
1018        keys: &'b CompiledTapeKeys,
1019    ) -> impl Iterator<Item = Option<TapeValue<'a>>> + 'b {
1020        keys.iter().map(|key| self.get_compiled(key))
1021    }
1022}
1023
1024
1025impl fmt::Display for JsonValue {
1026    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1027        match self.to_json_string() {
1028            Ok(json) => f.write_str(&json),
1029            Err(_) => Err(fmt::Error),
1030        }
1031    }
1032}
1033
1034static JSON_NULL: JsonValue = JsonValue::Null;
1035
1036fn object_get<'a>(entries: &'a [(String, JsonValue)], key: &str) -> Option<&'a JsonValue> {
1037    entries
1038        .iter()
1039        .find(|(candidate, _)| candidate == key)
1040        .map(|(_, value)| value)
1041}
1042
1043fn object_get_mut<'a>(entries: &'a mut Vec<(String, JsonValue)>, key: &str) -> Option<&'a mut JsonValue> {
1044    entries
1045        .iter_mut()
1046        .find(|(candidate, _)| candidate == key)
1047        .map(|(_, value)| value)
1048}
1049
1050fn object_index_or_insert<'a>(value: &'a mut JsonValue, key: &str) -> &'a mut JsonValue {
1051    if matches!(value, JsonValue::Null) {
1052        *value = JsonValue::Object(Vec::new());
1053    }
1054    match value {
1055        JsonValue::Object(entries) => {
1056            if let Some(pos) = entries.iter().position(|(candidate, _)| candidate == key) {
1057                &mut entries[pos].1
1058            } else {
1059                entries.push((key.to_owned(), JsonValue::Null));
1060                &mut entries.last_mut().unwrap().1
1061            }
1062        }
1063        JsonValue::Null => unreachable!(),
1064        JsonValue::Bool(_) => panic!("cannot access key {:?} in JSON boolean", key),
1065        JsonValue::Number(_) => panic!("cannot access key {:?} in JSON number", key),
1066        JsonValue::String(_) => panic!("cannot access key {:?} in JSON string", key),
1067        JsonValue::Array(_) => panic!("cannot access key {:?} in JSON array", key),
1068    }
1069}
1070
1071fn array_index_or_panic(value: &mut JsonValue, index: usize) -> &mut JsonValue {
1072    match value {
1073        JsonValue::Array(values) => {
1074            let len = values.len();
1075            values.get_mut(index).unwrap_or_else(|| panic!("cannot access index {} of JSON array of length {}", index, len))
1076        }
1077        JsonValue::Null => panic!("cannot access index {} of JSON null", index),
1078        JsonValue::Bool(_) => panic!("cannot access index {} of JSON boolean", index),
1079        JsonValue::Number(_) => panic!("cannot access index {} of JSON number", index),
1080        JsonValue::String(_) => panic!("cannot access index {} of JSON string", index),
1081        JsonValue::Object(_) => panic!("cannot access index {} of JSON object", index),
1082    }
1083}
1084
1085impl Index<&str> for JsonValue {
1086    type Output = JsonValue;
1087
1088    fn index(&self, index: &str) -> &Self::Output {
1089        match self {
1090            JsonValue::Object(entries) => object_get(entries, index).unwrap_or(&JSON_NULL),
1091            _ => &JSON_NULL,
1092        }
1093    }
1094}
1095
1096impl Index<String> for JsonValue {
1097    type Output = JsonValue;
1098
1099    fn index(&self, index: String) -> &Self::Output {
1100        self.index(index.as_str())
1101    }
1102}
1103
1104impl Index<usize> for JsonValue {
1105    type Output = JsonValue;
1106
1107    fn index(&self, index: usize) -> &Self::Output {
1108        match self {
1109            JsonValue::Array(values) => values.get(index).unwrap_or(&JSON_NULL),
1110            _ => &JSON_NULL,
1111        }
1112    }
1113}
1114
1115impl IndexMut<&str> for JsonValue {
1116    fn index_mut(&mut self, index: &str) -> &mut Self::Output {
1117        object_index_or_insert(self, index)
1118    }
1119}
1120
1121impl IndexMut<String> for JsonValue {
1122    fn index_mut(&mut self, index: String) -> &mut Self::Output {
1123        object_index_or_insert(self, &index)
1124    }
1125}
1126
1127impl IndexMut<usize> for JsonValue {
1128    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1129        array_index_or_panic(self, index)
1130    }
1131}
1132
1133#[macro_export]
1134macro_rules! json {
1135    (null) => {
1136        $crate::JsonValue::Null
1137    };
1138    ([$($element:tt),* $(,)?]) => {
1139        $crate::JsonValue::Array(vec![$($crate::json!($element)),*])
1140    };
1141    ({$($key:literal : $value:tt),* $(,)?}) => {
1142        $crate::JsonValue::Object(vec![$(($key.to_owned(), $crate::json!($value))),*])
1143    };
1144    ($other:expr) => {
1145        $crate::JsonValue::from($other)
1146    };
1147}
1148
1149fn decode_pointer_segment(segment: &str) -> String {
1150    let mut out = String::with_capacity(segment.len());
1151    let bytes = segment.as_bytes();
1152    let mut i = 0;
1153    while i < bytes.len() {
1154        if bytes[i] == b'~' && i + 1 < bytes.len() {
1155            match bytes[i + 1] {
1156                b'0' => {
1157                    out.push('~');
1158                    i += 2;
1159                    continue;
1160                }
1161                b'1' => {
1162                    out.push('/');
1163                    i += 2;
1164                    continue;
1165                }
1166                _ => {}
1167            }
1168        }
1169        out.push(bytes[i] as char);
1170        i += 1;
1171    }
1172    out
1173}
1174
1175fn write_indent(out: &mut Vec<u8>, depth: usize) {
1176    for _ in 0..depth {
1177        out.extend_from_slice(b"  ");
1178    }
1179}
1180
1181fn write_json_value_pretty(out: &mut Vec<u8>, value: &JsonValue, depth: usize) -> Result<(), JsonError> {
1182    match value {
1183        JsonValue::Null | JsonValue::Bool(_) | JsonValue::Number(_) | JsonValue::String(_) => {
1184            write_json_value(out, value)
1185        }
1186        JsonValue::Array(values) => {
1187            out.push(b'[');
1188            if !values.is_empty() {
1189                out.push(b'\n');
1190                for (index, value) in values.iter().enumerate() {
1191                    if index > 0 {
1192                        out.extend_from_slice(b",\n");
1193                    }
1194                    write_indent(out, depth + 1);
1195                    write_json_value_pretty(out, value, depth + 1)?;
1196                }
1197                out.push(b'\n');
1198                write_indent(out, depth);
1199            }
1200            out.push(b']');
1201            Ok(())
1202        }
1203        JsonValue::Object(entries) => {
1204            out.push(b'{');
1205            if !entries.is_empty() {
1206                out.push(b'\n');
1207                for (index, (key, value)) in entries.iter().enumerate() {
1208                    if index > 0 {
1209                        out.extend_from_slice(b",\n");
1210                    }
1211                    write_indent(out, depth + 1);
1212                    write_json_key(out, key);
1213                    out.push(b' ');
1214                    write_json_value_pretty(out, value, depth + 1)?;
1215                }
1216                out.push(b'\n');
1217                write_indent(out, depth);
1218            }
1219            out.push(b'}');
1220            Ok(())
1221        }
1222    }
1223}
1224
1225fn hash_key(bytes: &[u8]) -> u64 {
1226    let mut hash = 1469598103934665603u64;
1227    for &byte in bytes {
1228        hash ^= byte as u64;
1229        hash = hash.wrapping_mul(1099511628211u64);
1230    }
1231    hash
1232}
1233
1234#[inline]
1235fn write_json_value(out: &mut Vec<u8>, value: &JsonValue) -> Result<(), JsonError> {
1236    match value {
1237        JsonValue::Null => out.extend_from_slice(b"null"),
1238        JsonValue::Bool(value) => {
1239            if *value {
1240                out.extend_from_slice(b"true");
1241            } else {
1242                out.extend_from_slice(b"false");
1243            }
1244        }
1245        JsonValue::Number(number) => write_json_number(out, number)?,
1246        JsonValue::String(value) => {
1247            write_escaped_json_string(out, value);
1248        }
1249        JsonValue::Array(values) => {
1250            write_json_array(out, values)?;
1251        }
1252        JsonValue::Object(entries) => {
1253            write_json_object(out, entries)?;
1254        }
1255    }
1256    Ok(())
1257}
1258
1259#[inline]
1260fn write_json_number(out: &mut Vec<u8>, value: &JsonNumber) -> Result<(), JsonError> {
1261    match value {
1262        JsonNumber::I64(value) => {
1263            append_i64(out, *value);
1264            Ok(())
1265        }
1266        JsonNumber::U64(value) => {
1267            append_u64(out, *value);
1268            Ok(())
1269        }
1270        JsonNumber::F64(value) => {
1271            if !value.is_finite() {
1272                return Err(JsonError::NonFiniteNumber);
1273            }
1274            out.extend_from_slice(value.to_string().as_bytes());
1275            Ok(())
1276        }
1277    }
1278}
1279
1280#[inline]
1281fn write_escaped_json_string(out: &mut Vec<u8>, input: &str) {
1282    out.push(b'"');
1283    let bytes = input.as_bytes();
1284    let mut fast_index = 0usize;
1285    while fast_index < bytes.len() {
1286        let byte = bytes[fast_index];
1287        if needs_escape(byte) {
1288            break;
1289        }
1290        fast_index += 1;
1291    }
1292    if fast_index == bytes.len() {
1293        out.extend_from_slice(bytes);
1294        out.push(b'"');
1295        return;
1296    }
1297
1298    if fast_index > 0 {
1299        out.extend_from_slice(&bytes[..fast_index]);
1300    }
1301
1302    let mut chunk_start = fast_index;
1303    for (index, byte) in bytes.iter().copied().enumerate().skip(fast_index) {
1304        let escape = match byte {
1305            b'"' => Some(br#"\""#.as_slice()),
1306            b'\\' => Some(br#"\\"#.as_slice()),
1307            0x08 => Some(br#"\b"#.as_slice()),
1308            0x0c => Some(br#"\f"#.as_slice()),
1309            b'\n' => Some(br#"\n"#.as_slice()),
1310            b'\r' => Some(br#"\r"#.as_slice()),
1311            b'\t' => Some(br#"\t"#.as_slice()),
1312            _ => None,
1313        };
1314        if let Some(escape) = escape {
1315            if chunk_start < index {
1316                out.extend_from_slice(&bytes[chunk_start..index]);
1317            }
1318            out.extend_from_slice(escape);
1319            chunk_start = index + 1;
1320            continue;
1321        }
1322        if byte <= 0x1f {
1323            if chunk_start < index {
1324                out.extend_from_slice(&bytes[chunk_start..index]);
1325            }
1326            out.extend_from_slice(br#"\u00"#);
1327            out.push(hex_digit((byte >> 4) & 0x0f));
1328            out.push(hex_digit(byte & 0x0f));
1329            chunk_start = index + 1;
1330        }
1331    }
1332    if chunk_start < input.len() {
1333        out.extend_from_slice(&bytes[chunk_start..]);
1334    }
1335    out.push(b'"');
1336}
1337
1338#[inline]
1339fn needs_escape(byte: u8) -> bool {
1340    matches!(byte, b'"' | b'\\' | 0x00..=0x1f)
1341}
1342
1343#[inline]
1344fn write_json_array(out: &mut Vec<u8>, values: &[JsonValue]) -> Result<(), JsonError> {
1345    out.push(b'[');
1346    match values {
1347        [] => {}
1348        [one] => {
1349            write_json_value(out, one)?;
1350        }
1351        [a, b] => {
1352            write_json_value(out, a)?;
1353            out.push(b',');
1354            write_json_value(out, b)?;
1355        }
1356        [a, b, c] => {
1357            write_json_value(out, a)?;
1358            out.push(b',');
1359            write_json_value(out, b)?;
1360            out.push(b',');
1361            write_json_value(out, c)?;
1362        }
1363        _ => {
1364            let mut iter = values.iter();
1365            if let Some(first) = iter.next() {
1366                write_json_value(out, first)?;
1367                for value in iter {
1368                    out.push(b',');
1369                    write_json_value(out, value)?;
1370                }
1371            }
1372        }
1373    }
1374    out.push(b']');
1375    Ok(())
1376}
1377
1378#[inline]
1379fn write_json_object(out: &mut Vec<u8>, entries: &[(String, JsonValue)]) -> Result<(), JsonError> {
1380    out.push(b'{');
1381    match entries {
1382        [] => {}
1383        [(k1, v1)] => {
1384            write_json_key(out, k1);
1385            write_json_value(out, v1)?;
1386        }
1387        [(k1, v1), (k2, v2)] => {
1388            write_json_key(out, k1);
1389            write_json_value(out, v1)?;
1390            out.push(b',');
1391            write_json_key(out, k2);
1392            write_json_value(out, v2)?;
1393        }
1394        [(k1, v1), (k2, v2), (k3, v3)] => {
1395            write_json_key(out, k1);
1396            write_json_value(out, v1)?;
1397            out.push(b',');
1398            write_json_key(out, k2);
1399            write_json_value(out, v2)?;
1400            out.push(b',');
1401            write_json_key(out, k3);
1402            write_json_value(out, v3)?;
1403        }
1404        _ => {
1405            let mut iter = entries.iter();
1406            if let Some((first_key, first_value)) = iter.next() {
1407                write_json_key(out, first_key);
1408                write_json_value(out, first_value)?;
1409                for (key, value) in iter {
1410                    out.push(b',');
1411                    write_json_key(out, key);
1412                    write_json_value(out, value)?;
1413                }
1414            }
1415        }
1416    }
1417    out.push(b'}');
1418    Ok(())
1419}
1420
1421#[inline]
1422fn write_json_key(out: &mut Vec<u8>, key: &str) {
1423    let bytes = key.as_bytes();
1424    if is_plain_json_string(bytes) {
1425        out.push(b'"');
1426        out.extend_from_slice(bytes);
1427        out.extend_from_slice(b"\":");
1428    } else {
1429        write_escaped_json_string(out, key);
1430        out.push(b':');
1431    }
1432}
1433
1434#[inline]
1435fn is_plain_json_string(bytes: &[u8]) -> bool {
1436    for &byte in bytes {
1437        if needs_escape(byte) {
1438            return false;
1439        }
1440    }
1441    true
1442}
1443
1444fn initial_json_capacity(value: &JsonValue) -> usize {
1445    match value {
1446        JsonValue::Null => 4,
1447        JsonValue::Bool(true) => 4,
1448        JsonValue::Bool(false) => 5,
1449        JsonValue::Number(JsonNumber::I64(value)) => estimate_i64_len(*value),
1450        JsonValue::Number(JsonNumber::U64(value)) => estimate_u64_len(*value),
1451        JsonValue::Number(JsonNumber::F64(_)) => 24,
1452        JsonValue::String(value) => estimate_escaped_string_len(value),
1453        JsonValue::Array(values) => 2 + values.len().saturating_mul(16),
1454        JsonValue::Object(entries) => {
1455            2 + entries
1456                .iter()
1457                .map(|(key, _)| estimate_escaped_string_len(key) + 8)
1458                .sum::<usize>()
1459        }
1460    }
1461}
1462
1463fn estimate_escaped_string_len(value: &str) -> usize {
1464    let mut len = 2;
1465    for ch in value.chars() {
1466        len += match ch {
1467            '"' | '\\' | '\u{08}' | '\u{0C}' | '\n' | '\r' | '\t' => 2,
1468            ch if ch <= '\u{1F}' => 6,
1469            ch => ch.len_utf8(),
1470        };
1471    }
1472    len
1473}
1474
1475fn estimate_u64_len(mut value: u64) -> usize {
1476    let mut len = 1;
1477    while value >= 10 {
1478        value /= 10;
1479        len += 1;
1480    }
1481    len
1482}
1483
1484fn estimate_i64_len(value: i64) -> usize {
1485    if value < 0 {
1486        1 + estimate_u64_len(value.unsigned_abs())
1487    } else {
1488        estimate_u64_len(value as u64)
1489    }
1490}
1491
1492fn append_i64(out: &mut Vec<u8>, value: i64) {
1493    if value < 0 {
1494        out.push(b'-');
1495        append_u64(out, value.unsigned_abs());
1496    } else {
1497        append_u64(out, value as u64);
1498    }
1499}
1500
1501fn append_u64(out: &mut Vec<u8>, mut value: u64) {
1502    let mut buf = [0u8; 20];
1503    let mut index = buf.len();
1504    loop {
1505        index -= 1;
1506        buf[index] = b'0' + (value % 10) as u8;
1507        value /= 10;
1508        if value == 0 {
1509            break;
1510        }
1511    }
1512    out.extend_from_slice(&buf[index..]);
1513}
1514
1515fn hex_digit(value: u8) -> u8 {
1516    match value {
1517        0..=9 => b'0' + value,
1518        10..=15 => b'a' + (value - 10),
1519        _ => unreachable!(),
1520    }
1521}
1522
1523struct Parser<'a> {
1524    input: &'a str,
1525    bytes: &'a [u8],
1526    index: usize,
1527}
1528
1529impl<'a> Parser<'a> {
1530    fn new(input: &'a str) -> Self {
1531        Self {
1532            input,
1533            bytes: input.as_bytes(),
1534            index: 0,
1535        }
1536    }
1537
1538    fn parse_value(&mut self) -> Result<JsonValue, JsonParseError> {
1539        self.skip_whitespace();
1540        match self.peek_byte() {
1541            Some(b'n') => self.parse_literal(b"null", JsonValue::Null),
1542            Some(b't') => self.parse_literal(b"true", JsonValue::Bool(true)),
1543            Some(b'f') => self.parse_literal(b"false", JsonValue::Bool(false)),
1544            Some(b'"') => Ok(JsonValue::String(self.parse_string()?)),
1545            Some(b'[') => self.parse_array(),
1546            Some(b'{') => self.parse_object(),
1547            Some(b'-' | b'0'..=b'9') => self.parse_number().map(JsonValue::Number),
1548            Some(found) => Err(JsonParseError::UnexpectedCharacter {
1549                index: self.index,
1550                found: found as char,
1551            }),
1552            None => Err(JsonParseError::UnexpectedEnd),
1553        }
1554    }
1555
1556    fn parse_value_borrowed(&mut self) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1557        self.skip_whitespace();
1558        match self.peek_byte() {
1559            Some(b'n') => self.parse_literal_borrowed(b"null", BorrowedJsonValue::Null),
1560            Some(b't') => self.parse_literal_borrowed(b"true", BorrowedJsonValue::Bool(true)),
1561            Some(b'f') => self.parse_literal_borrowed(b"false", BorrowedJsonValue::Bool(false)),
1562            Some(b'"') => Ok(BorrowedJsonValue::String(self.parse_string_borrowed()?)),
1563            Some(b'[') => self.parse_array_borrowed(),
1564            Some(b'{') => self.parse_object_borrowed(),
1565            Some(b'-' | b'0'..=b'9') => self.parse_number().map(BorrowedJsonValue::Number),
1566            Some(found) => Err(JsonParseError::UnexpectedCharacter {
1567                index: self.index,
1568                found: found as char,
1569            }),
1570            None => Err(JsonParseError::UnexpectedEnd),
1571        }
1572    }
1573
1574    fn parse_tape_value(
1575        &mut self,
1576        tokens: &mut Vec<TapeToken>,
1577        parent: Option<usize>,
1578    ) -> Result<usize, JsonParseError> {
1579        self.skip_whitespace();
1580        match self.peek_byte() {
1581            Some(b'n') => self.parse_tape_literal(tokens, parent, b"null", TapeTokenKind::Null),
1582            Some(b't') => self.parse_tape_literal(tokens, parent, b"true", TapeTokenKind::Bool),
1583            Some(b'f') => self.parse_tape_literal(tokens, parent, b"false", TapeTokenKind::Bool),
1584            Some(b'"') => self.parse_tape_string(tokens, parent, TapeTokenKind::String),
1585            Some(b'[') => self.parse_tape_array(tokens, parent),
1586            Some(b'{') => self.parse_tape_object(tokens, parent),
1587            Some(b'-' | b'0'..=b'9') => self.parse_tape_number(tokens, parent),
1588            Some(found) => Err(JsonParseError::UnexpectedCharacter {
1589                index: self.index,
1590                found: found as char,
1591            }),
1592            None => Err(JsonParseError::UnexpectedEnd),
1593        }
1594    }
1595
1596    fn parse_literal(
1597        &mut self,
1598        expected: &[u8],
1599        value: JsonValue,
1600    ) -> Result<JsonValue, JsonParseError> {
1601        if self.bytes[self.index..].starts_with(expected) {
1602            self.index += expected.len();
1603            Ok(value)
1604        } else {
1605            Err(JsonParseError::InvalidLiteral { index: self.index })
1606        }
1607    }
1608
1609    fn parse_literal_borrowed(
1610        &mut self,
1611        expected: &[u8],
1612        value: BorrowedJsonValue<'a>,
1613    ) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1614        if self.bytes[self.index..].starts_with(expected) {
1615            self.index += expected.len();
1616            Ok(value)
1617        } else {
1618            Err(JsonParseError::InvalidLiteral { index: self.index })
1619        }
1620    }
1621
1622    fn parse_tape_literal(
1623        &mut self,
1624        tokens: &mut Vec<TapeToken>,
1625        parent: Option<usize>,
1626        expected: &[u8],
1627        kind: TapeTokenKind,
1628    ) -> Result<usize, JsonParseError> {
1629        let start = self.index;
1630        if self.bytes[self.index..].starts_with(expected) {
1631            self.index += expected.len();
1632            let token_index = tokens.len();
1633            tokens.push(TapeToken {
1634                kind,
1635                start,
1636                end: self.index,
1637                parent,
1638            });
1639            Ok(token_index)
1640        } else {
1641            Err(JsonParseError::InvalidLiteral { index: self.index })
1642        }
1643    }
1644
1645    fn parse_array(&mut self) -> Result<JsonValue, JsonParseError> {
1646        self.consume_byte(b'[')?;
1647        self.skip_whitespace();
1648        let mut values = Vec::new();
1649        if self.try_consume_byte(b']') {
1650            return Ok(JsonValue::Array(values));
1651        }
1652        loop {
1653            values.push(self.parse_value()?);
1654            self.skip_whitespace();
1655            if self.try_consume_byte(b']') {
1656                break;
1657            }
1658            if !self.try_consume_byte(b',') {
1659                return Err(JsonParseError::ExpectedCommaOrEnd {
1660                    index: self.index,
1661                    context: "array",
1662                });
1663            }
1664            self.skip_whitespace();
1665        }
1666        Ok(JsonValue::Array(values))
1667    }
1668
1669    fn parse_array_borrowed(&mut self) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1670        self.consume_byte(b'[')?;
1671        self.skip_whitespace();
1672        let mut values = Vec::new();
1673        if self.try_consume_byte(b']') {
1674            return Ok(BorrowedJsonValue::Array(values));
1675        }
1676        loop {
1677            values.push(self.parse_value_borrowed()?);
1678            self.skip_whitespace();
1679            if self.try_consume_byte(b']') {
1680                break;
1681            }
1682            if !self.try_consume_byte(b',') {
1683                return Err(JsonParseError::ExpectedCommaOrEnd {
1684                    index: self.index,
1685                    context: "array",
1686                });
1687            }
1688            self.skip_whitespace();
1689        }
1690        Ok(BorrowedJsonValue::Array(values))
1691    }
1692
1693    fn parse_tape_array(
1694        &mut self,
1695        tokens: &mut Vec<TapeToken>,
1696        parent: Option<usize>,
1697    ) -> Result<usize, JsonParseError> {
1698        let start = self.index;
1699        self.consume_byte(b'[')?;
1700        let token_index = tokens.len();
1701        tokens.push(TapeToken {
1702            kind: TapeTokenKind::Array,
1703            start,
1704            end: start,
1705            parent,
1706        });
1707        self.skip_whitespace();
1708        if self.try_consume_byte(b']') {
1709            tokens[token_index].end = self.index;
1710            return Ok(token_index);
1711        }
1712        loop {
1713            self.parse_tape_value(tokens, Some(token_index))?;
1714            self.skip_whitespace();
1715            if self.try_consume_byte(b']') {
1716                tokens[token_index].end = self.index;
1717                break;
1718            }
1719            if !self.try_consume_byte(b',') {
1720                return Err(JsonParseError::ExpectedCommaOrEnd {
1721                    index: self.index,
1722                    context: "array",
1723                });
1724            }
1725            self.skip_whitespace();
1726        }
1727        Ok(token_index)
1728    }
1729
1730    fn parse_object(&mut self) -> Result<JsonValue, JsonParseError> {
1731        self.consume_byte(b'{')?;
1732        self.skip_whitespace();
1733        let mut entries = Vec::new();
1734        if self.try_consume_byte(b'}') {
1735            return Ok(JsonValue::Object(entries));
1736        }
1737        loop {
1738            if self.peek_byte() != Some(b'"') {
1739                return match self.peek_byte() {
1740                    Some(found) => Err(JsonParseError::UnexpectedCharacter {
1741                        index: self.index,
1742                        found: found as char,
1743                    }),
1744                    None => Err(JsonParseError::UnexpectedEnd),
1745                };
1746            }
1747            let key = self.parse_string()?;
1748            self.skip_whitespace();
1749            if !self.try_consume_byte(b':') {
1750                return Err(JsonParseError::ExpectedColon { index: self.index });
1751            }
1752            let value = self.parse_value()?;
1753            entries.push((key, value));
1754            self.skip_whitespace();
1755            if self.try_consume_byte(b'}') {
1756                break;
1757            }
1758            if !self.try_consume_byte(b',') {
1759                return Err(JsonParseError::ExpectedCommaOrEnd {
1760                    index: self.index,
1761                    context: "object",
1762                });
1763            }
1764            self.skip_whitespace();
1765        }
1766        Ok(JsonValue::Object(entries))
1767    }
1768
1769    fn parse_object_borrowed(&mut self) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1770        self.consume_byte(b'{')?;
1771        self.skip_whitespace();
1772        let mut entries = Vec::new();
1773        if self.try_consume_byte(b'}') {
1774            return Ok(BorrowedJsonValue::Object(entries));
1775        }
1776        loop {
1777            if self.peek_byte() != Some(b'"') {
1778                return match self.peek_byte() {
1779                    Some(found) => Err(JsonParseError::UnexpectedCharacter {
1780                        index: self.index,
1781                        found: found as char,
1782                    }),
1783                    None => Err(JsonParseError::UnexpectedEnd),
1784                };
1785            }
1786            let key = self.parse_string_borrowed()?;
1787            self.skip_whitespace();
1788            if !self.try_consume_byte(b':') {
1789                return Err(JsonParseError::ExpectedColon { index: self.index });
1790            }
1791            let value = self.parse_value_borrowed()?;
1792            entries.push((key, value));
1793            self.skip_whitespace();
1794            if self.try_consume_byte(b'}') {
1795                break;
1796            }
1797            if !self.try_consume_byte(b',') {
1798                return Err(JsonParseError::ExpectedCommaOrEnd {
1799                    index: self.index,
1800                    context: "object",
1801                });
1802            }
1803            self.skip_whitespace();
1804        }
1805        Ok(BorrowedJsonValue::Object(entries))
1806    }
1807
1808    fn parse_tape_object(
1809        &mut self,
1810        tokens: &mut Vec<TapeToken>,
1811        parent: Option<usize>,
1812    ) -> Result<usize, JsonParseError> {
1813        let start = self.index;
1814        self.consume_byte(b'{')?;
1815        let token_index = tokens.len();
1816        tokens.push(TapeToken {
1817            kind: TapeTokenKind::Object,
1818            start,
1819            end: start,
1820            parent,
1821        });
1822        self.skip_whitespace();
1823        if self.try_consume_byte(b'}') {
1824            tokens[token_index].end = self.index;
1825            return Ok(token_index);
1826        }
1827        loop {
1828            if self.peek_byte() != Some(b'"') {
1829                return match self.peek_byte() {
1830                    Some(found) => Err(JsonParseError::UnexpectedCharacter {
1831                        index: self.index,
1832                        found: found as char,
1833                    }),
1834                    None => Err(JsonParseError::UnexpectedEnd),
1835                };
1836            }
1837            self.parse_tape_string(tokens, Some(token_index), TapeTokenKind::Key)?;
1838            self.skip_whitespace();
1839            if !self.try_consume_byte(b':') {
1840                return Err(JsonParseError::ExpectedColon { index: self.index });
1841            }
1842            self.parse_tape_value(tokens, Some(token_index))?;
1843            self.skip_whitespace();
1844            if self.try_consume_byte(b'}') {
1845                tokens[token_index].end = self.index;
1846                break;
1847            }
1848            if !self.try_consume_byte(b',') {
1849                return Err(JsonParseError::ExpectedCommaOrEnd {
1850                    index: self.index,
1851                    context: "object",
1852                });
1853            }
1854            self.skip_whitespace();
1855        }
1856        Ok(token_index)
1857    }
1858
1859    fn parse_string(&mut self) -> Result<String, JsonParseError> {
1860        self.consume_byte(b'"')?;
1861        let start = self.index;
1862        loop {
1863            let Some(byte) = self.next_byte() else {
1864                return Err(JsonParseError::UnexpectedEnd);
1865            };
1866            match byte {
1867                b'"' => {
1868                    let slice = &self.input[start..self.index - 1];
1869                    return Ok(slice.to_owned());
1870                }
1871                b'\\' => {
1872                    let mut out = String::with_capacity(self.index - start + 8);
1873                    out.push_str(&self.input[start..self.index - 1]);
1874                    self.parse_escape_into(&mut out, self.index - 1)?;
1875                    return self.parse_string_slow(out);
1876                }
1877                0x00..=0x1f => {
1878                    return Err(JsonParseError::UnexpectedCharacter {
1879                        index: self.index - 1,
1880                        found: byte as char,
1881                    })
1882                }
1883                _ => {}
1884            }
1885        }
1886    }
1887
1888    fn parse_string_borrowed(&mut self) -> Result<Cow<'a, str>, JsonParseError> {
1889        self.consume_byte(b'"')?;
1890        let start = self.index;
1891        loop {
1892            let Some(byte) = self.next_byte() else {
1893                return Err(JsonParseError::UnexpectedEnd);
1894            };
1895            match byte {
1896                b'"' => {
1897                    let slice = &self.input[start..self.index - 1];
1898                    return Ok(Cow::Borrowed(slice));
1899                }
1900                b'\\' => {
1901                    let mut out = String::with_capacity(self.index - start + 8);
1902                    out.push_str(&self.input[start..self.index - 1]);
1903                    self.parse_escape_into(&mut out, self.index - 1)?;
1904                    return self.parse_string_slow_borrowed(out);
1905                }
1906                0x00..=0x1f => {
1907                    return Err(JsonParseError::UnexpectedCharacter {
1908                        index: self.index - 1,
1909                        found: byte as char,
1910                    })
1911                }
1912                _ => {}
1913            }
1914        }
1915    }
1916
1917    fn parse_tape_string(
1918        &mut self,
1919        tokens: &mut Vec<TapeToken>,
1920        parent: Option<usize>,
1921        kind: TapeTokenKind,
1922    ) -> Result<usize, JsonParseError> {
1923        let start = self.index;
1924        self.skip_string_bytes()?;
1925        let token_index = tokens.len();
1926        tokens.push(TapeToken {
1927            kind,
1928            start,
1929            end: self.index,
1930            parent,
1931        });
1932        Ok(token_index)
1933    }
1934
1935    fn skip_string_bytes(&mut self) -> Result<(), JsonParseError> {
1936        self.consume_byte(b'"')?;
1937        loop {
1938            let Some(byte) = self.next_byte() else {
1939                return Err(JsonParseError::UnexpectedEnd);
1940            };
1941            match byte {
1942                b'"' => return Ok(()),
1943                b'\\' => {
1944                    let escape_index = self.index - 1;
1945                    let escaped = self.next_byte().ok_or(JsonParseError::UnexpectedEnd)?;
1946                    match escaped {
1947                        b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {}
1948                        b'u' => {
1949                            let scalar = self.parse_hex_quad(escape_index)?;
1950                            if (0xD800..=0xDBFF).contains(&scalar) {
1951                                if self.next_byte() != Some(b'\\') || self.next_byte() != Some(b'u')
1952                                {
1953                                    return Err(JsonParseError::InvalidUnicodeScalar {
1954                                        index: escape_index,
1955                                    });
1956                                }
1957                                let low = self.parse_hex_quad(escape_index)?;
1958                                if !(0xDC00..=0xDFFF).contains(&low) {
1959                                    return Err(JsonParseError::InvalidUnicodeScalar {
1960                                        index: escape_index,
1961                                    });
1962                                }
1963                            } else if (0xDC00..=0xDFFF).contains(&scalar) {
1964                                return Err(JsonParseError::InvalidUnicodeScalar {
1965                                    index: escape_index,
1966                                });
1967                            }
1968                        }
1969                        _ => {
1970                            return Err(JsonParseError::InvalidEscape {
1971                                index: escape_index,
1972                            })
1973                        }
1974                    }
1975                }
1976                0x00..=0x1f => {
1977                    return Err(JsonParseError::UnexpectedCharacter {
1978                        index: self.index - 1,
1979                        found: byte as char,
1980                    })
1981                }
1982                _ => {}
1983            }
1984        }
1985    }
1986
1987    fn parse_string_slow(&mut self, mut out: String) -> Result<String, JsonParseError> {
1988        let mut chunk_start = self.index;
1989        loop {
1990            let Some(byte) = self.next_byte() else {
1991                return Err(JsonParseError::UnexpectedEnd);
1992            };
1993            match byte {
1994                b'"' => {
1995                    if chunk_start < self.index - 1 {
1996                        out.push_str(&self.input[chunk_start..self.index - 1]);
1997                    }
1998                    return Ok(out);
1999                }
2000                b'\\' => {
2001                    if chunk_start < self.index - 1 {
2002                        out.push_str(&self.input[chunk_start..self.index - 1]);
2003                    }
2004                    self.parse_escape_into(&mut out, self.index - 1)?;
2005                    chunk_start = self.index;
2006                }
2007                0x00..=0x1f => {
2008                    return Err(JsonParseError::UnexpectedCharacter {
2009                        index: self.index - 1,
2010                        found: byte as char,
2011                    })
2012                }
2013                _ => {}
2014            }
2015        }
2016    }
2017
2018    fn parse_string_slow_borrowed(
2019        &mut self,
2020        mut out: String,
2021    ) -> Result<Cow<'a, str>, JsonParseError> {
2022        let mut chunk_start = self.index;
2023        loop {
2024            let Some(byte) = self.next_byte() else {
2025                return Err(JsonParseError::UnexpectedEnd);
2026            };
2027            match byte {
2028                b'"' => {
2029                    if chunk_start < self.index - 1 {
2030                        out.push_str(&self.input[chunk_start..self.index - 1]);
2031                    }
2032                    return Ok(Cow::Owned(out));
2033                }
2034                b'\\' => {
2035                    if chunk_start < self.index - 1 {
2036                        out.push_str(&self.input[chunk_start..self.index - 1]);
2037                    }
2038                    self.parse_escape_into(&mut out, self.index - 1)?;
2039                    chunk_start = self.index;
2040                }
2041                0x00..=0x1f => {
2042                    return Err(JsonParseError::UnexpectedCharacter {
2043                        index: self.index - 1,
2044                        found: byte as char,
2045                    })
2046                }
2047                _ => {}
2048            }
2049        }
2050    }
2051
2052    fn parse_escape_into(
2053        &mut self,
2054        out: &mut String,
2055        escape_index: usize,
2056    ) -> Result<(), JsonParseError> {
2057        let escaped = self.next_byte().ok_or(JsonParseError::UnexpectedEnd)?;
2058        match escaped {
2059            b'"' => out.push('"'),
2060            b'\\' => out.push('\\'),
2061            b'/' => out.push('/'),
2062            b'b' => out.push('\u{0008}'),
2063            b'f' => out.push('\u{000C}'),
2064            b'n' => out.push('\n'),
2065            b'r' => out.push('\r'),
2066            b't' => out.push('\t'),
2067            b'u' => out.push(self.parse_unicode_escape(escape_index)?),
2068            _ => {
2069                return Err(JsonParseError::InvalidEscape {
2070                    index: escape_index,
2071                })
2072            }
2073        }
2074        Ok(())
2075    }
2076
2077    fn parse_unicode_escape(&mut self, index: usize) -> Result<char, JsonParseError> {
2078        let scalar = self.parse_hex_quad(index)?;
2079        if (0xD800..=0xDBFF).contains(&scalar) {
2080            if self.next_byte() != Some(b'\\') || self.next_byte() != Some(b'u') {
2081                return Err(JsonParseError::InvalidUnicodeScalar { index });
2082            }
2083            let low = self.parse_hex_quad(index)?;
2084            if !(0xDC00..=0xDFFF).contains(&low) {
2085                return Err(JsonParseError::InvalidUnicodeScalar { index });
2086            }
2087            let high = scalar - 0xD800;
2088            let low = low - 0xDC00;
2089            let combined = 0x10000 + ((high << 10) | low);
2090            char::from_u32(combined).ok_or(JsonParseError::InvalidUnicodeScalar { index })
2091        } else if (0xDC00..=0xDFFF).contains(&scalar) {
2092            Err(JsonParseError::InvalidUnicodeScalar { index })
2093        } else {
2094            char::from_u32(scalar).ok_or(JsonParseError::InvalidUnicodeScalar { index })
2095        }
2096    }
2097
2098    fn parse_hex_quad(&mut self, index: usize) -> Result<u32, JsonParseError> {
2099        let mut value = 0u32;
2100        for _ in 0..4 {
2101            let ch = self.next_byte().ok_or(JsonParseError::UnexpectedEnd)?;
2102            let digit = match ch {
2103                b'0'..=b'9' => (ch - b'0') as u32,
2104                b'a'..=b'f' => 10 + (ch - b'a') as u32,
2105                b'A'..=b'F' => 10 + (ch - b'A') as u32,
2106                _ => return Err(JsonParseError::InvalidUnicodeEscape { index }),
2107            };
2108            value = (value << 4) | digit;
2109        }
2110        Ok(value)
2111    }
2112
2113    fn parse_number(&mut self) -> Result<JsonNumber, JsonParseError> {
2114        let start = self.index;
2115        self.try_consume_byte(b'-');
2116        if self.try_consume_byte(b'0') {
2117            if matches!(self.peek_byte(), Some(b'0'..=b'9')) {
2118                return Err(JsonParseError::InvalidNumber { index: start });
2119            }
2120        } else {
2121            self.consume_digits(start)?;
2122        }
2123
2124        let mut is_float = false;
2125        if self.try_consume_byte(b'.') {
2126            is_float = true;
2127            self.consume_digits(start)?;
2128        }
2129        if matches!(self.peek_byte(), Some(b'e' | b'E')) {
2130            is_float = true;
2131            self.index += 1;
2132            if matches!(self.peek_byte(), Some(b'+' | b'-')) {
2133                self.index += 1;
2134            }
2135            self.consume_digits(start)?;
2136        }
2137
2138        let token = &self.input[start..self.index];
2139        if is_float {
2140            let value = token
2141                .parse::<f64>()
2142                .map_err(|_| JsonParseError::InvalidNumber { index: start })?;
2143            if !value.is_finite() {
2144                return Err(JsonParseError::InvalidNumber { index: start });
2145            }
2146            Ok(JsonNumber::F64(value))
2147        } else if token.starts_with('-') {
2148            let value = token
2149                .parse::<i64>()
2150                .map_err(|_| JsonParseError::InvalidNumber { index: start })?;
2151            Ok(JsonNumber::I64(value))
2152        } else {
2153            let value = token
2154                .parse::<u64>()
2155                .map_err(|_| JsonParseError::InvalidNumber { index: start })?;
2156            Ok(JsonNumber::U64(value))
2157        }
2158    }
2159
2160    fn parse_tape_number(
2161        &mut self,
2162        tokens: &mut Vec<TapeToken>,
2163        parent: Option<usize>,
2164    ) -> Result<usize, JsonParseError> {
2165        let start = self.index;
2166        let _ = self.parse_number()?;
2167        let token_index = tokens.len();
2168        tokens.push(TapeToken {
2169            kind: TapeTokenKind::Number,
2170            start,
2171            end: self.index,
2172            parent,
2173        });
2174        Ok(token_index)
2175    }
2176
2177    fn consume_digits(&mut self, index: usize) -> Result<(), JsonParseError> {
2178        let start = self.index;
2179        while matches!(self.peek_byte(), Some(b'0'..=b'9')) {
2180            self.index += 1;
2181        }
2182        if self.index == start {
2183            return Err(JsonParseError::InvalidNumber { index });
2184        }
2185        Ok(())
2186    }
2187
2188    fn consume_byte(&mut self, expected: u8) -> Result<(), JsonParseError> {
2189        match self.next_byte() {
2190            Some(found) if found == expected => Ok(()),
2191            Some(found) => Err(JsonParseError::UnexpectedCharacter {
2192                index: self.index.saturating_sub(1),
2193                found: found as char,
2194            }),
2195            None => Err(JsonParseError::UnexpectedEnd),
2196        }
2197    }
2198
2199    fn try_consume_byte(&mut self, expected: u8) -> bool {
2200        if self.peek_byte() == Some(expected) {
2201            self.index += 1;
2202            true
2203        } else {
2204            false
2205        }
2206    }
2207
2208    fn skip_whitespace(&mut self) {
2209        while matches!(self.peek_byte(), Some(b' ' | b'\n' | b'\r' | b'\t')) {
2210            self.index += 1;
2211        }
2212    }
2213
2214    fn peek_byte(&self) -> Option<u8> {
2215        self.bytes.get(self.index).copied()
2216    }
2217
2218    fn next_byte(&mut self) -> Option<u8> {
2219        let byte = self.peek_byte()?;
2220        self.index += 1;
2221        Some(byte)
2222    }
2223
2224    fn is_eof(&self) -> bool {
2225        self.index >= self.input.len()
2226    }
2227}
2228
2229#[cfg(test)]
2230mod tests {
2231    use super::*;
2232
2233    #[test]
2234    fn escapes_control_characters_and_quotes() {
2235        let escaped = escape_json_string("hello\t\"world\"\n\u{0007}");
2236        assert_eq!(escaped, "\"hello\\t\\\"world\\\"\\n\\u0007\"");
2237    }
2238
2239    #[test]
2240    fn serializes_nested_values() {
2241        let value = JsonValue::object(vec![
2242            ("name", "node-1".into()),
2243            ("ok", true.into()),
2244            (
2245                "values",
2246                JsonValue::array(vec![1u32.into(), 2u32.into(), JsonValue::Null]),
2247            ),
2248        ]);
2249        assert_eq!(
2250            value.to_json_string().unwrap(),
2251            "{\"name\":\"node-1\",\"ok\":true,\"values\":[1,2,null]}"
2252        );
2253    }
2254
2255    #[test]
2256    fn rejects_non_finite_float() {
2257        let value = JsonValue::from(f64::NAN);
2258        assert_eq!(value.to_json_string(), Err(JsonError::NonFiniteNumber));
2259    }
2260
2261    #[test]
2262    fn parses_basic_json_values() {
2263        assert_eq!(parse_json("null").unwrap(), JsonValue::Null);
2264        assert_eq!(parse_json("true").unwrap(), JsonValue::Bool(true));
2265        assert_eq!(
2266            parse_json("\"hello\"").unwrap(),
2267            JsonValue::String("hello".into())
2268        );
2269        assert_eq!(
2270            parse_json("123").unwrap(),
2271            JsonValue::Number(JsonNumber::U64(123))
2272        );
2273        assert_eq!(
2274            parse_json("-123").unwrap(),
2275            JsonValue::Number(JsonNumber::I64(-123))
2276        );
2277    }
2278
2279    #[test]
2280    fn parses_unicode_and_escapes() {
2281        let value = parse_json("\"line\\n\\u03bb\\uD83D\\uDE80\"").unwrap();
2282        assert_eq!(value, JsonValue::String("line\nλ🚀".into()));
2283    }
2284
2285    #[test]
2286    fn borrowed_parse_avoids_allocating_plain_strings() {
2287        let value = parse_json_borrowed("{\"name\":\"hello\",\"n\":1}").unwrap();
2288        match value {
2289            BorrowedJsonValue::Object(entries) => {
2290                assert!(matches!(entries[0].0, Cow::Borrowed(_)));
2291                assert!(matches!(
2292                    entries[0].1,
2293                    BorrowedJsonValue::String(Cow::Borrowed(_))
2294                ));
2295            }
2296            other => panic!("unexpected value: {other:?}"),
2297        }
2298    }
2299
2300    #[test]
2301    fn borrowed_parse_allocates_when_unescaping_is_needed() {
2302        let value = parse_json_borrowed("\"line\\nvalue\"").unwrap();
2303        match value {
2304            BorrowedJsonValue::String(Cow::Owned(text)) => assert_eq!(text, "line\nvalue"),
2305            other => panic!("unexpected value: {other:?}"),
2306        }
2307    }
2308
2309    #[test]
2310    fn compiled_schema_serializes_expected_shape() {
2311        let schema = CompiledObjectSchema::new(&["id", "name", "enabled"]);
2312        let values = [
2313            JsonValue::from(7u64),
2314            JsonValue::from("node-7"),
2315            JsonValue::from(true),
2316        ];
2317        let json = schema.to_json_string(values.iter()).unwrap();
2318        assert_eq!(json, "{\"id\":7,\"name\":\"node-7\",\"enabled\":true}");
2319    }
2320
2321    #[test]
2322    fn compiled_row_schema_serializes_array_of_objects() {
2323        let schema = CompiledRowSchema::new(&["id", "name"]);
2324        let row1 = [JsonValue::from(1u64), JsonValue::from("a")];
2325        let row2 = [JsonValue::from(2u64), JsonValue::from("b")];
2326        let json = schema.to_json_string([row1.iter(), row2.iter()]).unwrap();
2327        assert_eq!(json, r#"[{"id":1,"name":"a"},{"id":2,"name":"b"}]"#);
2328    }
2329
2330    #[test]
2331    fn tape_parse_records_structure_tokens() {
2332        let tape = parse_json_tape(r#"{"a":[1,"x"],"b":true}"#).unwrap();
2333        assert_eq!(tape.tokens[0].kind, TapeTokenKind::Object);
2334        assert_eq!(tape.tokens[1].kind, TapeTokenKind::Key);
2335        assert_eq!(tape.tokens[2].kind, TapeTokenKind::Array);
2336        assert_eq!(tape.tokens[3].kind, TapeTokenKind::Number);
2337        assert_eq!(tape.tokens[4].kind, TapeTokenKind::String);
2338        assert_eq!(tape.tokens[5].kind, TapeTokenKind::Key);
2339        assert_eq!(tape.tokens[6].kind, TapeTokenKind::Bool);
2340    }
2341
2342    #[test]
2343    fn tape_object_lookup_finds_child_values() {
2344        let input = r#"{"name":"hello","nested":{"x":1},"flag":true}"#;
2345        let tape = parse_json_tape(input).unwrap();
2346        let root = tape.root(input).unwrap();
2347        let name = root.get("name").unwrap();
2348        assert_eq!(name.kind(), TapeTokenKind::String);
2349        assert_eq!(name.as_str(), Some("hello"));
2350        let nested = root.get("nested").unwrap();
2351        assert_eq!(nested.kind(), TapeTokenKind::Object);
2352        assert!(root.get("missing").is_none());
2353    }
2354
2355    #[test]
2356    fn tape_object_index_lookup_finds_child_values() {
2357        let input = r#"{"name":"hello","nested":{"x":1},"flag":true}"#;
2358        let tape = parse_json_tape(input).unwrap();
2359        let root = tape.root(input).unwrap();
2360        let index = root.build_object_index().unwrap();
2361        let flag = index.get(root, "flag").unwrap();
2362        assert_eq!(flag.kind(), TapeTokenKind::Bool);
2363        assert!(index.get(root, "missing").is_none());
2364    }
2365
2366    #[test]
2367    fn indexed_tape_object_compiled_lookup_finds_child_values() {
2368        let input = r#"{"name":"hello","nested":{"x":1},"flag":true}"#;
2369        let tape = parse_json_tape(input).unwrap();
2370        let root = tape.root(input).unwrap();
2371        let index = root.build_object_index().unwrap();
2372        let indexed = root.with_index(&index);
2373        let keys = CompiledTapeKeys::new(&["name", "flag", "missing"]);
2374        let got = indexed
2375            .get_compiled_many(&keys)
2376            .map(|value| value.map(|value| value.kind()))
2377            .collect::<Vec<_>>();
2378        assert_eq!(got, vec![Some(TapeTokenKind::String), Some(TapeTokenKind::Bool), None]);
2379    }
2380
2381    #[test]
2382    fn serde_style_convenience_api_works() {
2383        let value = from_str(r#"{"ok":true,"n":7,"items":[1,2,3],"msg":"hello"}"#).unwrap();
2384        assert!(value.is_object());
2385        assert_eq!(value["ok"].as_bool(), Some(true));
2386        assert_eq!(value["n"].as_i64(), Some(7));
2387        assert_eq!(value["msg"].as_str(), Some("hello"));
2388        assert_eq!(value["items"][1].as_u64(), Some(2));
2389        assert!(value["missing"].is_null());
2390        assert_eq!(to_string(&value).unwrap(), r#"{"ok":true,"n":7,"items":[1,2,3],"msg":"hello"}"#);
2391        assert_eq!(from_slice(br#"[1,true,"x"]"#).unwrap()[2].as_str(), Some("x"));
2392        assert_eq!(to_vec(&value).unwrap(), value.to_json_string().unwrap().into_bytes());
2393    }
2394
2395    #[test]
2396    fn json_macro_builds_values() {
2397        let value = json!({"ok": true, "items": [1, 2, null], "msg": "x"});
2398        assert_eq!(value["ok"].as_bool(), Some(true));
2399        assert_eq!(value["items"][0].as_u64(), Some(1));
2400        assert!(value["items"][2].is_null());
2401        assert_eq!(value["msg"].as_str(), Some("x"));
2402    }
2403
2404    #[test]
2405    fn from_slice_rejects_invalid_utf8() {
2406        assert!(matches!(from_slice(&[0xff]), Err(JsonParseError::InvalidUtf8)));
2407    }
2408
2409    #[test]
2410    fn pointer_take_and_pretty_helpers_work() {
2411        let mut value = from_str(r#"{"a":{"b":[10,20,{"~key/":"x"}]}}"#).unwrap();
2412        assert_eq!(value.pointer("/a/b/1").and_then(JsonValue::as_u64), Some(20));
2413        assert_eq!(value.pointer("/a/b/2/~0key~1").and_then(JsonValue::as_str), Some("x"));
2414        *value.pointer_mut("/a/b/0").unwrap() = JsonValue::from(99u64);
2415        assert_eq!(value.pointer("/a/b/0").and_then(JsonValue::as_u64), Some(99));
2416
2417        let taken = value.pointer_mut("/a/b/2").unwrap().take();
2418        assert!(value.pointer("/a/b/2").unwrap().is_null());
2419        assert_eq!(taken["~key/"].as_str(), Some("x"));
2420
2421        let pretty = to_string_pretty(&value).unwrap();
2422        assert!(pretty.contains("\"a\": {"));
2423        let mut out = Vec::new();
2424        to_writer_pretty(&mut out, &value).unwrap();
2425        assert_eq!(String::from_utf8(out).unwrap(), pretty);
2426    }
2427
2428    #[test]
2429    fn reader_writer_and_collection_helpers_work() {
2430        let value = from_reader(std::io::Cursor::new(br#"{"a":1,"b":[true,false]}"# as &[u8])).unwrap();
2431        assert_eq!(value["a"].as_u64(), Some(1));
2432        assert_eq!(value["b"].len(), 2);
2433        assert_eq!(value["b"].get_index(1).and_then(JsonValue::as_bool), Some(false));
2434
2435        let mut out = Vec::new();
2436        to_writer(&mut out, &value).unwrap();
2437        assert_eq!(String::from_utf8(out).unwrap(), value.to_json_string().unwrap());
2438
2439        let object = JsonValue::from_iter([("x", 1u64), ("y", 2u64)]);
2440        assert_eq!(object["x"].as_u64(), Some(1));
2441        let array = JsonValue::from_iter([1u64, 2u64, 3u64]);
2442        assert_eq!(array.get_index(2).and_then(JsonValue::as_u64), Some(3));
2443    }
2444
2445    #[test]
2446    fn number_and_mut_index_parity_helpers_work() {
2447        let int = JsonValue::from(7i64);
2448        assert!(int.is_i64());
2449        assert!(!int.is_u64());
2450        assert!(!int.is_f64());
2451        assert_eq!(int.as_number().and_then(JsonNumber::as_i64), Some(7));
2452
2453        let float = JsonValue::Number(JsonNumber::from_f64(2.5).unwrap());
2454        assert!(float.is_f64());
2455        assert_eq!(float.as_f64(), Some(2.5));
2456        assert_eq!(JsonValue::Null.as_null(), Some(()));
2457
2458        let mut value = JsonValue::Null;
2459        value["a"]["b"]["c"] = JsonValue::from(true);
2460        assert_eq!(value.pointer("/a/b/c").and_then(JsonValue::as_bool), Some(true));
2461
2462        value["arr"] = json!([1, 2, 3]);
2463        value["arr"][1] = JsonValue::from(9u64);
2464        assert_eq!(value.pointer("/arr/1").and_then(JsonValue::as_u64), Some(9));
2465    }
2466
2467    #[test]
2468    fn rejects_invalid_json_inputs() {
2469        assert!(matches!(
2470            parse_json("{"),
2471            Err(JsonParseError::UnexpectedEnd)
2472        ));
2473        assert!(matches!(
2474            parse_json("{\"a\" 1}"),
2475            Err(JsonParseError::ExpectedColon { .. })
2476        ));
2477        assert!(matches!(
2478            parse_json("[1 2]"),
2479            Err(JsonParseError::ExpectedCommaOrEnd {
2480                context: "array",
2481                ..
2482            })
2483        ));
2484        assert!(matches!(
2485            parse_json("{\"a\":1 trailing"),
2486            Err(JsonParseError::ExpectedCommaOrEnd {
2487                context: "object",
2488                ..
2489            })
2490        ));
2491        assert!(matches!(
2492            parse_json("00"),
2493            Err(JsonParseError::InvalidNumber { .. })
2494        ));
2495    }
2496
2497    #[test]
2498    fn roundtrips_specific_structures() {
2499        let values = [
2500            JsonValue::Null,
2501            JsonValue::Bool(false),
2502            JsonValue::String("tab\tquote\"slash\\snowman☃".into()),
2503            JsonValue::Number(JsonNumber::I64(-9_223_372_036_854_775_808)),
2504            JsonValue::Number(JsonNumber::U64(u64::MAX)),
2505            JsonValue::Number(JsonNumber::F64(12345.125)),
2506            JsonValue::Array(vec![
2507                JsonValue::Bool(true),
2508                JsonValue::String("nested".into()),
2509                JsonValue::Object(vec![("x".into(), 1u64.into())]),
2510            ]),
2511        ];
2512        for value in values {
2513            let text = value.to_json_string().unwrap();
2514            let reparsed = parse_json(&text).unwrap();
2515            assert_json_equivalent(&value, &reparsed);
2516        }
2517    }
2518
2519    #[test]
2520    fn deterministic_fuzz_roundtrip_strings_and_values() {
2521        let mut rng = Rng::new(0x5eed_1234_5678_9abc);
2522        for _ in 0..2_000 {
2523            let input = random_string(&mut rng, 48);
2524            let escaped = escape_json_string(&input);
2525            let parsed = parse_json(&escaped).unwrap();
2526            assert_eq!(parsed, JsonValue::String(input));
2527        }
2528
2529        for _ in 0..1_000 {
2530            let value = random_json_value(&mut rng, 0, 4);
2531            let text = value.to_json_string().unwrap();
2532            let reparsed = parse_json(&text).unwrap();
2533            assert_json_equivalent(&value, &reparsed);
2534        }
2535    }
2536
2537    fn assert_json_equivalent(expected: &JsonValue, actual: &JsonValue) {
2538        match (expected, actual) {
2539            (JsonValue::Null, JsonValue::Null) => {}
2540            (JsonValue::Bool(a), JsonValue::Bool(b)) => assert_eq!(a, b),
2541            (JsonValue::String(a), JsonValue::String(b)) => assert_eq!(a, b),
2542            (JsonValue::Number(a), JsonValue::Number(b)) => assert_numbers_equivalent(a, b),
2543            (JsonValue::Array(a), JsonValue::Array(b)) => {
2544                assert_eq!(a.len(), b.len());
2545                for (left, right) in a.iter().zip(b.iter()) {
2546                    assert_json_equivalent(left, right);
2547                }
2548            }
2549            (JsonValue::Object(a), JsonValue::Object(b)) => {
2550                assert_eq!(a.len(), b.len());
2551                for ((left_key, left_value), (right_key, right_value)) in a.iter().zip(b.iter()) {
2552                    assert_eq!(left_key, right_key);
2553                    assert_json_equivalent(left_value, right_value);
2554                }
2555            }
2556            _ => panic!("json values differ: expected {expected:?}, actual {actual:?}"),
2557        }
2558    }
2559
2560    fn assert_numbers_equivalent(expected: &JsonNumber, actual: &JsonNumber) {
2561        match (expected, actual) {
2562            (JsonNumber::I64(a), JsonNumber::I64(b)) => assert_eq!(a, b),
2563            (JsonNumber::U64(a), JsonNumber::U64(b)) => assert_eq!(a, b),
2564            (JsonNumber::F64(a), JsonNumber::F64(b)) => assert_eq!(a.to_bits(), b.to_bits()),
2565            (JsonNumber::I64(a), JsonNumber::U64(b)) if *a >= 0 => assert_eq!(*a as u64, *b),
2566            (JsonNumber::U64(a), JsonNumber::I64(b)) if *b >= 0 => assert_eq!(*a, *b as u64),
2567            (JsonNumber::I64(a), JsonNumber::F64(b)) => assert_eq!(*a as f64, *b),
2568            (JsonNumber::U64(a), JsonNumber::F64(b)) => assert_eq!(*a as f64, *b),
2569            (JsonNumber::F64(a), JsonNumber::I64(b)) => assert_eq!(*a, *b as f64),
2570            (JsonNumber::F64(a), JsonNumber::U64(b)) => assert_eq!(*a, *b as f64),
2571            (left, right) => panic!("json numbers differ: expected {left:?}, actual {right:?}"),
2572        }
2573    }
2574
2575    #[derive(Clone, Debug)]
2576    struct Rng {
2577        state: u64,
2578    }
2579
2580    impl Rng {
2581        fn new(seed: u64) -> Self {
2582            Self { state: seed }
2583        }
2584
2585        fn next_u64(&mut self) -> u64 {
2586            self.state = self
2587                .state
2588                .wrapping_mul(6364136223846793005)
2589                .wrapping_add(1442695040888963407);
2590            self.state
2591        }
2592
2593        fn choose(&mut self, upper_exclusive: usize) -> usize {
2594            (self.next_u64() % upper_exclusive as u64) as usize
2595        }
2596
2597        fn bool(&mut self) -> bool {
2598            (self.next_u64() & 1) == 1
2599        }
2600    }
2601
2602    fn random_string(rng: &mut Rng, max_len: usize) -> String {
2603        let len = rng.choose(max_len + 1);
2604        let mut out = String::new();
2605        for _ in 0..len {
2606            let ch = match rng.choose(12) {
2607                0 => '"',
2608                1 => '\\',
2609                2 => '\n',
2610                3 => '\r',
2611                4 => '\t',
2612                5 => '\u{0007}',
2613                6 => 'λ',
2614                7 => '🚀',
2615                8 => '☃',
2616                _ => (b'a' + rng.choose(26) as u8) as char,
2617            };
2618            out.push(ch);
2619        }
2620        out
2621    }
2622
2623    fn random_json_value(rng: &mut Rng, depth: usize, max_depth: usize) -> JsonValue {
2624        if depth >= max_depth {
2625            return random_leaf(rng);
2626        }
2627        match rng.choose(7) {
2628            0 | 1 | 2 | 3 => random_leaf(rng),
2629            4 => {
2630                let len = rng.choose(5);
2631                let mut values = Vec::with_capacity(len);
2632                for _ in 0..len {
2633                    values.push(random_json_value(rng, depth + 1, max_depth));
2634                }
2635                JsonValue::Array(values)
2636            }
2637            _ => {
2638                let len = rng.choose(5);
2639                let mut entries = Vec::with_capacity(len);
2640                for index in 0..len {
2641                    entries.push((
2642                        format!("k{depth}_{index}_{}", random_string(rng, 6)),
2643                        random_json_value(rng, depth + 1, max_depth),
2644                    ));
2645                }
2646                JsonValue::Object(entries)
2647            }
2648        }
2649    }
2650
2651    fn random_leaf(rng: &mut Rng) -> JsonValue {
2652        match rng.choose(6) {
2653            0 => JsonValue::Null,
2654            1 => JsonValue::Bool(rng.bool()),
2655            2 => JsonValue::String(random_string(rng, 24)),
2656            3 => JsonValue::Number(JsonNumber::I64(
2657                (rng.next_u64() >> 1) as i64 * if rng.bool() { 1 } else { -1 },
2658            )),
2659            4 => JsonValue::Number(JsonNumber::U64(rng.next_u64())),
2660            _ => {
2661                let mantissa = (rng.next_u64() % 1_000_000) as f64 / 1000.0;
2662                let sign = if rng.bool() { 1.0 } else { -1.0 };
2663                JsonValue::Number(JsonNumber::F64(sign * mantissa))
2664            }
2665        }
2666    }
2667}