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<I>(&self, index: I) -> Option<&JsonValue>
351    where
352        I: ValueIndex,
353    {
354        index.index_into(self)
355    }
356
357    pub fn get_mut<I>(&mut self, index: I) -> Option<&mut JsonValue>
358    where
359        I: ValueIndex,
360    {
361        index.index_into_mut(self)
362    }
363
364    pub fn len(&self) -> usize {
365        match self {
366            Self::Array(values) => values.len(),
367            Self::Object(entries) => entries.len(),
368            _ => 0,
369        }
370    }
371
372    pub fn is_empty(&self) -> bool {
373        self.len() == 0
374    }
375
376    pub fn as_i128(&self) -> Option<i128> {
377        self.as_i64().map(|v| v as i128)
378    }
379
380    pub fn as_u128(&self) -> Option<u128> {
381        self.as_u64().map(|v| v as u128)
382    }
383
384    pub fn as_f32(&self) -> Option<f32> {
385        self.as_f64().map(|v| v as f32)
386    }
387
388    pub fn get_index(&self, index: usize) -> Option<&JsonValue> {
389        match self {
390            Self::Array(values) => values.get(index),
391            _ => None,
392        }
393    }
394
395    pub fn get_index_mut(&mut self, index: usize) -> Option<&mut JsonValue> {
396        match self {
397            Self::Array(values) => values.get_mut(index),
398            _ => None,
399        }
400    }
401
402    pub fn take(&mut self) -> JsonValue {
403        std::mem::replace(self, JsonValue::Null)
404    }
405
406    pub fn pointer(&self, pointer: &str) -> Option<&JsonValue> {
407        if pointer.is_empty() {
408            return Some(self);
409        }
410        if !pointer.starts_with('/') {
411            return None;
412        }
413        let mut current = self;
414        for segment in pointer.split('/').skip(1) {
415            let token = decode_pointer_segment(segment);
416            current = match current {
417                JsonValue::Object(entries) => entries
418                    .iter()
419                    .find(|(key, _)| key == &token)
420                    .map(|(_, value)| value)?,
421                JsonValue::Array(values) => values.get(token.parse::<usize>().ok()?)?,
422                _ => return None,
423            };
424        }
425        Some(current)
426    }
427
428    pub fn pointer_mut(&mut self, pointer: &str) -> Option<&mut JsonValue> {
429        if pointer.is_empty() {
430            return Some(self);
431        }
432        if !pointer.starts_with('/') {
433            return None;
434        }
435        let mut current = self;
436        for segment in pointer.split('/').skip(1) {
437            let token = decode_pointer_segment(segment);
438            current = match current {
439                JsonValue::Object(entries) => entries
440                    .iter_mut()
441                    .find(|(key, _)| key == &token)
442                    .map(|(_, value)| value)?,
443                JsonValue::Array(values) => values.get_mut(token.parse::<usize>().ok()?)?,
444                _ => return None,
445            };
446        }
447        Some(current)
448    }
449}
450
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
1036pub trait ValueIndex {
1037    fn index_into<'a>(&self, value: &'a JsonValue) -> Option<&'a JsonValue>;
1038    fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> Option<&'a mut JsonValue>;
1039}
1040
1041impl ValueIndex for usize {
1042    fn index_into<'a>(&self, value: &'a JsonValue) -> Option<&'a JsonValue> {
1043        match value {
1044            JsonValue::Array(values) => values.get(*self),
1045            _ => None,
1046        }
1047    }
1048
1049    fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> Option<&'a mut JsonValue> {
1050        match value {
1051            JsonValue::Array(values) => values.get_mut(*self),
1052            _ => None,
1053        }
1054    }
1055}
1056
1057impl ValueIndex for str {
1058    fn index_into<'a>(&self, value: &'a JsonValue) -> Option<&'a JsonValue> {
1059        match value {
1060            JsonValue::Object(entries) => object_get(entries, self),
1061            _ => None,
1062        }
1063    }
1064
1065    fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> Option<&'a mut JsonValue> {
1066        match value {
1067            JsonValue::Object(entries) => object_get_mut(entries, self),
1068            _ => None,
1069        }
1070    }
1071}
1072
1073impl ValueIndex for String {
1074    fn index_into<'a>(&self, value: &'a JsonValue) -> Option<&'a JsonValue> {
1075        self.as_str().index_into(value)
1076    }
1077
1078    fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> Option<&'a mut JsonValue> {
1079        self.as_str().index_into_mut(value)
1080    }
1081}
1082
1083impl<T> ValueIndex for &T
1084where
1085    T: ?Sized + ValueIndex,
1086{
1087    fn index_into<'a>(&self, value: &'a JsonValue) -> Option<&'a JsonValue> {
1088        (**self).index_into(value)
1089    }
1090
1091    fn index_into_mut<'a>(&self, value: &'a mut JsonValue) -> Option<&'a mut JsonValue> {
1092        (**self).index_into_mut(value)
1093    }
1094}
1095
1096fn object_get<'a>(entries: &'a [(String, JsonValue)], key: &str) -> Option<&'a JsonValue> {
1097    entries
1098        .iter()
1099        .find(|(candidate, _)| candidate == key)
1100        .map(|(_, value)| value)
1101}
1102
1103fn object_get_mut<'a>(entries: &'a mut Vec<(String, JsonValue)>, key: &str) -> Option<&'a mut JsonValue> {
1104    entries
1105        .iter_mut()
1106        .find(|(candidate, _)| candidate == key)
1107        .map(|(_, value)| value)
1108}
1109
1110fn object_index_or_insert<'a>(value: &'a mut JsonValue, key: &str) -> &'a mut JsonValue {
1111    if matches!(value, JsonValue::Null) {
1112        *value = JsonValue::Object(Vec::new());
1113    }
1114    match value {
1115        JsonValue::Object(entries) => {
1116            if let Some(pos) = entries.iter().position(|(candidate, _)| candidate == key) {
1117                &mut entries[pos].1
1118            } else {
1119                entries.push((key.to_owned(), JsonValue::Null));
1120                &mut entries.last_mut().unwrap().1
1121            }
1122        }
1123        JsonValue::Null => unreachable!(),
1124        JsonValue::Bool(_) => panic!("cannot access key {:?} in JSON boolean", key),
1125        JsonValue::Number(_) => panic!("cannot access key {:?} in JSON number", key),
1126        JsonValue::String(_) => panic!("cannot access key {:?} in JSON string", key),
1127        JsonValue::Array(_) => panic!("cannot access key {:?} in JSON array", key),
1128    }
1129}
1130
1131fn array_index_or_panic(value: &mut JsonValue, index: usize) -> &mut JsonValue {
1132    match value {
1133        JsonValue::Array(values) => {
1134            let len = values.len();
1135            values.get_mut(index).unwrap_or_else(|| panic!("cannot access index {} of JSON array of length {}", index, len))
1136        }
1137        JsonValue::Null => panic!("cannot access index {} of JSON null", index),
1138        JsonValue::Bool(_) => panic!("cannot access index {} of JSON boolean", index),
1139        JsonValue::Number(_) => panic!("cannot access index {} of JSON number", index),
1140        JsonValue::String(_) => panic!("cannot access index {} of JSON string", index),
1141        JsonValue::Object(_) => panic!("cannot access index {} of JSON object", index),
1142    }
1143}
1144
1145impl Index<&str> for JsonValue {
1146    type Output = JsonValue;
1147
1148    fn index(&self, index: &str) -> &Self::Output {
1149        match self {
1150            JsonValue::Object(entries) => object_get(entries, index).unwrap_or(&JSON_NULL),
1151            _ => &JSON_NULL,
1152        }
1153    }
1154}
1155
1156impl Index<String> for JsonValue {
1157    type Output = JsonValue;
1158
1159    fn index(&self, index: String) -> &Self::Output {
1160        self.index(index.as_str())
1161    }
1162}
1163
1164impl Index<usize> for JsonValue {
1165    type Output = JsonValue;
1166
1167    fn index(&self, index: usize) -> &Self::Output {
1168        match self {
1169            JsonValue::Array(values) => values.get(index).unwrap_or(&JSON_NULL),
1170            _ => &JSON_NULL,
1171        }
1172    }
1173}
1174
1175impl IndexMut<&str> for JsonValue {
1176    fn index_mut(&mut self, index: &str) -> &mut Self::Output {
1177        object_index_or_insert(self, index)
1178    }
1179}
1180
1181impl IndexMut<String> for JsonValue {
1182    fn index_mut(&mut self, index: String) -> &mut Self::Output {
1183        object_index_or_insert(self, &index)
1184    }
1185}
1186
1187impl IndexMut<usize> for JsonValue {
1188    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1189        array_index_or_panic(self, index)
1190    }
1191}
1192
1193#[macro_export]
1194macro_rules! json {
1195    (null) => {
1196        $crate::JsonValue::Null
1197    };
1198    ([$($element:tt),* $(,)?]) => {
1199        $crate::JsonValue::Array(vec![$($crate::json!($element)),*])
1200    };
1201    ({$($key:literal : $value:tt),* $(,)?}) => {
1202        $crate::JsonValue::Object(vec![$(($key.to_owned(), $crate::json!($value))),*])
1203    };
1204    ($other:expr) => {
1205        $crate::JsonValue::from($other)
1206    };
1207}
1208
1209fn decode_pointer_segment(segment: &str) -> String {
1210    let mut out = String::with_capacity(segment.len());
1211    let bytes = segment.as_bytes();
1212    let mut i = 0;
1213    while i < bytes.len() {
1214        if bytes[i] == b'~' && i + 1 < bytes.len() {
1215            match bytes[i + 1] {
1216                b'0' => {
1217                    out.push('~');
1218                    i += 2;
1219                    continue;
1220                }
1221                b'1' => {
1222                    out.push('/');
1223                    i += 2;
1224                    continue;
1225                }
1226                _ => {}
1227            }
1228        }
1229        out.push(bytes[i] as char);
1230        i += 1;
1231    }
1232    out
1233}
1234
1235fn write_indent(out: &mut Vec<u8>, depth: usize) {
1236    for _ in 0..depth {
1237        out.extend_from_slice(b"  ");
1238    }
1239}
1240
1241fn write_json_value_pretty(out: &mut Vec<u8>, value: &JsonValue, depth: usize) -> Result<(), JsonError> {
1242    match value {
1243        JsonValue::Null | JsonValue::Bool(_) | JsonValue::Number(_) | JsonValue::String(_) => {
1244            write_json_value(out, value)
1245        }
1246        JsonValue::Array(values) => {
1247            out.push(b'[');
1248            if !values.is_empty() {
1249                out.push(b'\n');
1250                for (index, value) in values.iter().enumerate() {
1251                    if index > 0 {
1252                        out.extend_from_slice(b",\n");
1253                    }
1254                    write_indent(out, depth + 1);
1255                    write_json_value_pretty(out, value, depth + 1)?;
1256                }
1257                out.push(b'\n');
1258                write_indent(out, depth);
1259            }
1260            out.push(b']');
1261            Ok(())
1262        }
1263        JsonValue::Object(entries) => {
1264            out.push(b'{');
1265            if !entries.is_empty() {
1266                out.push(b'\n');
1267                for (index, (key, value)) in entries.iter().enumerate() {
1268                    if index > 0 {
1269                        out.extend_from_slice(b",\n");
1270                    }
1271                    write_indent(out, depth + 1);
1272                    write_json_key(out, key);
1273                    out.push(b' ');
1274                    write_json_value_pretty(out, value, depth + 1)?;
1275                }
1276                out.push(b'\n');
1277                write_indent(out, depth);
1278            }
1279            out.push(b'}');
1280            Ok(())
1281        }
1282    }
1283}
1284
1285fn hash_key(bytes: &[u8]) -> u64 {
1286    let mut hash = 1469598103934665603u64;
1287    for &byte in bytes {
1288        hash ^= byte as u64;
1289        hash = hash.wrapping_mul(1099511628211u64);
1290    }
1291    hash
1292}
1293
1294#[inline]
1295fn write_json_value(out: &mut Vec<u8>, value: &JsonValue) -> Result<(), JsonError> {
1296    match value {
1297        JsonValue::Null => out.extend_from_slice(b"null"),
1298        JsonValue::Bool(value) => {
1299            if *value {
1300                out.extend_from_slice(b"true");
1301            } else {
1302                out.extend_from_slice(b"false");
1303            }
1304        }
1305        JsonValue::Number(number) => write_json_number(out, number)?,
1306        JsonValue::String(value) => {
1307            write_escaped_json_string(out, value);
1308        }
1309        JsonValue::Array(values) => {
1310            write_json_array(out, values)?;
1311        }
1312        JsonValue::Object(entries) => {
1313            write_json_object(out, entries)?;
1314        }
1315    }
1316    Ok(())
1317}
1318
1319#[inline]
1320fn write_json_number(out: &mut Vec<u8>, value: &JsonNumber) -> Result<(), JsonError> {
1321    match value {
1322        JsonNumber::I64(value) => {
1323            append_i64(out, *value);
1324            Ok(())
1325        }
1326        JsonNumber::U64(value) => {
1327            append_u64(out, *value);
1328            Ok(())
1329        }
1330        JsonNumber::F64(value) => {
1331            if !value.is_finite() {
1332                return Err(JsonError::NonFiniteNumber);
1333            }
1334            out.extend_from_slice(value.to_string().as_bytes());
1335            Ok(())
1336        }
1337    }
1338}
1339
1340#[inline]
1341fn write_escaped_json_string(out: &mut Vec<u8>, input: &str) {
1342    out.push(b'"');
1343    let bytes = input.as_bytes();
1344    let mut fast_index = 0usize;
1345    while fast_index < bytes.len() {
1346        let byte = bytes[fast_index];
1347        if needs_escape(byte) {
1348            break;
1349        }
1350        fast_index += 1;
1351    }
1352    if fast_index == bytes.len() {
1353        out.extend_from_slice(bytes);
1354        out.push(b'"');
1355        return;
1356    }
1357
1358    if fast_index > 0 {
1359        out.extend_from_slice(&bytes[..fast_index]);
1360    }
1361
1362    let mut chunk_start = fast_index;
1363    for (index, byte) in bytes.iter().copied().enumerate().skip(fast_index) {
1364        let escape = match byte {
1365            b'"' => Some(br#"\""#.as_slice()),
1366            b'\\' => Some(br#"\\"#.as_slice()),
1367            0x08 => Some(br#"\b"#.as_slice()),
1368            0x0c => Some(br#"\f"#.as_slice()),
1369            b'\n' => Some(br#"\n"#.as_slice()),
1370            b'\r' => Some(br#"\r"#.as_slice()),
1371            b'\t' => Some(br#"\t"#.as_slice()),
1372            _ => None,
1373        };
1374        if let Some(escape) = escape {
1375            if chunk_start < index {
1376                out.extend_from_slice(&bytes[chunk_start..index]);
1377            }
1378            out.extend_from_slice(escape);
1379            chunk_start = index + 1;
1380            continue;
1381        }
1382        if byte <= 0x1f {
1383            if chunk_start < index {
1384                out.extend_from_slice(&bytes[chunk_start..index]);
1385            }
1386            out.extend_from_slice(br#"\u00"#);
1387            out.push(hex_digit((byte >> 4) & 0x0f));
1388            out.push(hex_digit(byte & 0x0f));
1389            chunk_start = index + 1;
1390        }
1391    }
1392    if chunk_start < input.len() {
1393        out.extend_from_slice(&bytes[chunk_start..]);
1394    }
1395    out.push(b'"');
1396}
1397
1398#[inline]
1399fn needs_escape(byte: u8) -> bool {
1400    matches!(byte, b'"' | b'\\' | 0x00..=0x1f)
1401}
1402
1403#[inline]
1404fn write_json_array(out: &mut Vec<u8>, values: &[JsonValue]) -> Result<(), JsonError> {
1405    out.push(b'[');
1406    match values {
1407        [] => {}
1408        [one] => {
1409            write_json_value(out, one)?;
1410        }
1411        [a, b] => {
1412            write_json_value(out, a)?;
1413            out.push(b',');
1414            write_json_value(out, b)?;
1415        }
1416        [a, b, c] => {
1417            write_json_value(out, a)?;
1418            out.push(b',');
1419            write_json_value(out, b)?;
1420            out.push(b',');
1421            write_json_value(out, c)?;
1422        }
1423        _ => {
1424            let mut iter = values.iter();
1425            if let Some(first) = iter.next() {
1426                write_json_value(out, first)?;
1427                for value in iter {
1428                    out.push(b',');
1429                    write_json_value(out, value)?;
1430                }
1431            }
1432        }
1433    }
1434    out.push(b']');
1435    Ok(())
1436}
1437
1438#[inline]
1439fn write_json_object(out: &mut Vec<u8>, entries: &[(String, JsonValue)]) -> Result<(), JsonError> {
1440    out.push(b'{');
1441    match entries {
1442        [] => {}
1443        [(k1, v1)] => {
1444            write_json_key(out, k1);
1445            write_json_value(out, v1)?;
1446        }
1447        [(k1, v1), (k2, v2)] => {
1448            write_json_key(out, k1);
1449            write_json_value(out, v1)?;
1450            out.push(b',');
1451            write_json_key(out, k2);
1452            write_json_value(out, v2)?;
1453        }
1454        [(k1, v1), (k2, v2), (k3, v3)] => {
1455            write_json_key(out, k1);
1456            write_json_value(out, v1)?;
1457            out.push(b',');
1458            write_json_key(out, k2);
1459            write_json_value(out, v2)?;
1460            out.push(b',');
1461            write_json_key(out, k3);
1462            write_json_value(out, v3)?;
1463        }
1464        _ => {
1465            let mut iter = entries.iter();
1466            if let Some((first_key, first_value)) = iter.next() {
1467                write_json_key(out, first_key);
1468                write_json_value(out, first_value)?;
1469                for (key, value) in iter {
1470                    out.push(b',');
1471                    write_json_key(out, key);
1472                    write_json_value(out, value)?;
1473                }
1474            }
1475        }
1476    }
1477    out.push(b'}');
1478    Ok(())
1479}
1480
1481#[inline]
1482fn write_json_key(out: &mut Vec<u8>, key: &str) {
1483    let bytes = key.as_bytes();
1484    if is_plain_json_string(bytes) {
1485        out.push(b'"');
1486        out.extend_from_slice(bytes);
1487        out.extend_from_slice(b"\":");
1488    } else {
1489        write_escaped_json_string(out, key);
1490        out.push(b':');
1491    }
1492}
1493
1494#[inline]
1495fn is_plain_json_string(bytes: &[u8]) -> bool {
1496    for &byte in bytes {
1497        if needs_escape(byte) {
1498            return false;
1499        }
1500    }
1501    true
1502}
1503
1504fn initial_json_capacity(value: &JsonValue) -> usize {
1505    match value {
1506        JsonValue::Null => 4,
1507        JsonValue::Bool(true) => 4,
1508        JsonValue::Bool(false) => 5,
1509        JsonValue::Number(JsonNumber::I64(value)) => estimate_i64_len(*value),
1510        JsonValue::Number(JsonNumber::U64(value)) => estimate_u64_len(*value),
1511        JsonValue::Number(JsonNumber::F64(_)) => 24,
1512        JsonValue::String(value) => estimate_escaped_string_len(value),
1513        JsonValue::Array(values) => 2 + values.len().saturating_mul(16),
1514        JsonValue::Object(entries) => {
1515            2 + entries
1516                .iter()
1517                .map(|(key, _)| estimate_escaped_string_len(key) + 8)
1518                .sum::<usize>()
1519        }
1520    }
1521}
1522
1523fn estimate_escaped_string_len(value: &str) -> usize {
1524    let mut len = 2;
1525    for ch in value.chars() {
1526        len += match ch {
1527            '"' | '\\' | '\u{08}' | '\u{0C}' | '\n' | '\r' | '\t' => 2,
1528            ch if ch <= '\u{1F}' => 6,
1529            ch => ch.len_utf8(),
1530        };
1531    }
1532    len
1533}
1534
1535fn estimate_u64_len(mut value: u64) -> usize {
1536    let mut len = 1;
1537    while value >= 10 {
1538        value /= 10;
1539        len += 1;
1540    }
1541    len
1542}
1543
1544fn estimate_i64_len(value: i64) -> usize {
1545    if value < 0 {
1546        1 + estimate_u64_len(value.unsigned_abs())
1547    } else {
1548        estimate_u64_len(value as u64)
1549    }
1550}
1551
1552fn append_i64(out: &mut Vec<u8>, value: i64) {
1553    if value < 0 {
1554        out.push(b'-');
1555        append_u64(out, value.unsigned_abs());
1556    } else {
1557        append_u64(out, value as u64);
1558    }
1559}
1560
1561fn append_u64(out: &mut Vec<u8>, mut value: u64) {
1562    let mut buf = [0u8; 20];
1563    let mut index = buf.len();
1564    loop {
1565        index -= 1;
1566        buf[index] = b'0' + (value % 10) as u8;
1567        value /= 10;
1568        if value == 0 {
1569            break;
1570        }
1571    }
1572    out.extend_from_slice(&buf[index..]);
1573}
1574
1575fn hex_digit(value: u8) -> u8 {
1576    match value {
1577        0..=9 => b'0' + value,
1578        10..=15 => b'a' + (value - 10),
1579        _ => unreachable!(),
1580    }
1581}
1582
1583struct Parser<'a> {
1584    input: &'a str,
1585    bytes: &'a [u8],
1586    index: usize,
1587}
1588
1589impl<'a> Parser<'a> {
1590    fn new(input: &'a str) -> Self {
1591        Self {
1592            input,
1593            bytes: input.as_bytes(),
1594            index: 0,
1595        }
1596    }
1597
1598    fn parse_value(&mut self) -> Result<JsonValue, JsonParseError> {
1599        self.skip_whitespace();
1600        match self.peek_byte() {
1601            Some(b'n') => self.parse_literal(b"null", JsonValue::Null),
1602            Some(b't') => self.parse_literal(b"true", JsonValue::Bool(true)),
1603            Some(b'f') => self.parse_literal(b"false", JsonValue::Bool(false)),
1604            Some(b'"') => Ok(JsonValue::String(self.parse_string()?)),
1605            Some(b'[') => self.parse_array(),
1606            Some(b'{') => self.parse_object(),
1607            Some(b'-' | b'0'..=b'9') => self.parse_number().map(JsonValue::Number),
1608            Some(found) => Err(JsonParseError::UnexpectedCharacter {
1609                index: self.index,
1610                found: found as char,
1611            }),
1612            None => Err(JsonParseError::UnexpectedEnd),
1613        }
1614    }
1615
1616    fn parse_value_borrowed(&mut self) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1617        self.skip_whitespace();
1618        match self.peek_byte() {
1619            Some(b'n') => self.parse_literal_borrowed(b"null", BorrowedJsonValue::Null),
1620            Some(b't') => self.parse_literal_borrowed(b"true", BorrowedJsonValue::Bool(true)),
1621            Some(b'f') => self.parse_literal_borrowed(b"false", BorrowedJsonValue::Bool(false)),
1622            Some(b'"') => Ok(BorrowedJsonValue::String(self.parse_string_borrowed()?)),
1623            Some(b'[') => self.parse_array_borrowed(),
1624            Some(b'{') => self.parse_object_borrowed(),
1625            Some(b'-' | b'0'..=b'9') => self.parse_number().map(BorrowedJsonValue::Number),
1626            Some(found) => Err(JsonParseError::UnexpectedCharacter {
1627                index: self.index,
1628                found: found as char,
1629            }),
1630            None => Err(JsonParseError::UnexpectedEnd),
1631        }
1632    }
1633
1634    fn parse_tape_value(
1635        &mut self,
1636        tokens: &mut Vec<TapeToken>,
1637        parent: Option<usize>,
1638    ) -> Result<usize, JsonParseError> {
1639        self.skip_whitespace();
1640        match self.peek_byte() {
1641            Some(b'n') => self.parse_tape_literal(tokens, parent, b"null", TapeTokenKind::Null),
1642            Some(b't') => self.parse_tape_literal(tokens, parent, b"true", TapeTokenKind::Bool),
1643            Some(b'f') => self.parse_tape_literal(tokens, parent, b"false", TapeTokenKind::Bool),
1644            Some(b'"') => self.parse_tape_string(tokens, parent, TapeTokenKind::String),
1645            Some(b'[') => self.parse_tape_array(tokens, parent),
1646            Some(b'{') => self.parse_tape_object(tokens, parent),
1647            Some(b'-' | b'0'..=b'9') => self.parse_tape_number(tokens, parent),
1648            Some(found) => Err(JsonParseError::UnexpectedCharacter {
1649                index: self.index,
1650                found: found as char,
1651            }),
1652            None => Err(JsonParseError::UnexpectedEnd),
1653        }
1654    }
1655
1656    fn parse_literal(
1657        &mut self,
1658        expected: &[u8],
1659        value: JsonValue,
1660    ) -> Result<JsonValue, JsonParseError> {
1661        if self.bytes[self.index..].starts_with(expected) {
1662            self.index += expected.len();
1663            Ok(value)
1664        } else {
1665            Err(JsonParseError::InvalidLiteral { index: self.index })
1666        }
1667    }
1668
1669    fn parse_literal_borrowed(
1670        &mut self,
1671        expected: &[u8],
1672        value: BorrowedJsonValue<'a>,
1673    ) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1674        if self.bytes[self.index..].starts_with(expected) {
1675            self.index += expected.len();
1676            Ok(value)
1677        } else {
1678            Err(JsonParseError::InvalidLiteral { index: self.index })
1679        }
1680    }
1681
1682    fn parse_tape_literal(
1683        &mut self,
1684        tokens: &mut Vec<TapeToken>,
1685        parent: Option<usize>,
1686        expected: &[u8],
1687        kind: TapeTokenKind,
1688    ) -> Result<usize, JsonParseError> {
1689        let start = self.index;
1690        if self.bytes[self.index..].starts_with(expected) {
1691            self.index += expected.len();
1692            let token_index = tokens.len();
1693            tokens.push(TapeToken {
1694                kind,
1695                start,
1696                end: self.index,
1697                parent,
1698            });
1699            Ok(token_index)
1700        } else {
1701            Err(JsonParseError::InvalidLiteral { index: self.index })
1702        }
1703    }
1704
1705    fn parse_array(&mut self) -> Result<JsonValue, JsonParseError> {
1706        self.consume_byte(b'[')?;
1707        self.skip_whitespace();
1708        let mut values = Vec::new();
1709        if self.try_consume_byte(b']') {
1710            return Ok(JsonValue::Array(values));
1711        }
1712        loop {
1713            values.push(self.parse_value()?);
1714            self.skip_whitespace();
1715            if self.try_consume_byte(b']') {
1716                break;
1717            }
1718            if !self.try_consume_byte(b',') {
1719                return Err(JsonParseError::ExpectedCommaOrEnd {
1720                    index: self.index,
1721                    context: "array",
1722                });
1723            }
1724            self.skip_whitespace();
1725        }
1726        Ok(JsonValue::Array(values))
1727    }
1728
1729    fn parse_array_borrowed(&mut self) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1730        self.consume_byte(b'[')?;
1731        self.skip_whitespace();
1732        let mut values = Vec::new();
1733        if self.try_consume_byte(b']') {
1734            return Ok(BorrowedJsonValue::Array(values));
1735        }
1736        loop {
1737            values.push(self.parse_value_borrowed()?);
1738            self.skip_whitespace();
1739            if self.try_consume_byte(b']') {
1740                break;
1741            }
1742            if !self.try_consume_byte(b',') {
1743                return Err(JsonParseError::ExpectedCommaOrEnd {
1744                    index: self.index,
1745                    context: "array",
1746                });
1747            }
1748            self.skip_whitespace();
1749        }
1750        Ok(BorrowedJsonValue::Array(values))
1751    }
1752
1753    fn parse_tape_array(
1754        &mut self,
1755        tokens: &mut Vec<TapeToken>,
1756        parent: Option<usize>,
1757    ) -> Result<usize, JsonParseError> {
1758        let start = self.index;
1759        self.consume_byte(b'[')?;
1760        let token_index = tokens.len();
1761        tokens.push(TapeToken {
1762            kind: TapeTokenKind::Array,
1763            start,
1764            end: start,
1765            parent,
1766        });
1767        self.skip_whitespace();
1768        if self.try_consume_byte(b']') {
1769            tokens[token_index].end = self.index;
1770            return Ok(token_index);
1771        }
1772        loop {
1773            self.parse_tape_value(tokens, Some(token_index))?;
1774            self.skip_whitespace();
1775            if self.try_consume_byte(b']') {
1776                tokens[token_index].end = self.index;
1777                break;
1778            }
1779            if !self.try_consume_byte(b',') {
1780                return Err(JsonParseError::ExpectedCommaOrEnd {
1781                    index: self.index,
1782                    context: "array",
1783                });
1784            }
1785            self.skip_whitespace();
1786        }
1787        Ok(token_index)
1788    }
1789
1790    fn parse_object(&mut self) -> Result<JsonValue, JsonParseError> {
1791        self.consume_byte(b'{')?;
1792        self.skip_whitespace();
1793        let mut entries = Vec::new();
1794        if self.try_consume_byte(b'}') {
1795            return Ok(JsonValue::Object(entries));
1796        }
1797        loop {
1798            if self.peek_byte() != Some(b'"') {
1799                return match self.peek_byte() {
1800                    Some(found) => Err(JsonParseError::UnexpectedCharacter {
1801                        index: self.index,
1802                        found: found as char,
1803                    }),
1804                    None => Err(JsonParseError::UnexpectedEnd),
1805                };
1806            }
1807            let key = self.parse_string()?;
1808            self.skip_whitespace();
1809            if !self.try_consume_byte(b':') {
1810                return Err(JsonParseError::ExpectedColon { index: self.index });
1811            }
1812            let value = self.parse_value()?;
1813            entries.push((key, value));
1814            self.skip_whitespace();
1815            if self.try_consume_byte(b'}') {
1816                break;
1817            }
1818            if !self.try_consume_byte(b',') {
1819                return Err(JsonParseError::ExpectedCommaOrEnd {
1820                    index: self.index,
1821                    context: "object",
1822                });
1823            }
1824            self.skip_whitespace();
1825        }
1826        Ok(JsonValue::Object(entries))
1827    }
1828
1829    fn parse_object_borrowed(&mut self) -> Result<BorrowedJsonValue<'a>, JsonParseError> {
1830        self.consume_byte(b'{')?;
1831        self.skip_whitespace();
1832        let mut entries = Vec::new();
1833        if self.try_consume_byte(b'}') {
1834            return Ok(BorrowedJsonValue::Object(entries));
1835        }
1836        loop {
1837            if self.peek_byte() != Some(b'"') {
1838                return match self.peek_byte() {
1839                    Some(found) => Err(JsonParseError::UnexpectedCharacter {
1840                        index: self.index,
1841                        found: found as char,
1842                    }),
1843                    None => Err(JsonParseError::UnexpectedEnd),
1844                };
1845            }
1846            let key = self.parse_string_borrowed()?;
1847            self.skip_whitespace();
1848            if !self.try_consume_byte(b':') {
1849                return Err(JsonParseError::ExpectedColon { index: self.index });
1850            }
1851            let value = self.parse_value_borrowed()?;
1852            entries.push((key, value));
1853            self.skip_whitespace();
1854            if self.try_consume_byte(b'}') {
1855                break;
1856            }
1857            if !self.try_consume_byte(b',') {
1858                return Err(JsonParseError::ExpectedCommaOrEnd {
1859                    index: self.index,
1860                    context: "object",
1861                });
1862            }
1863            self.skip_whitespace();
1864        }
1865        Ok(BorrowedJsonValue::Object(entries))
1866    }
1867
1868    fn parse_tape_object(
1869        &mut self,
1870        tokens: &mut Vec<TapeToken>,
1871        parent: Option<usize>,
1872    ) -> Result<usize, JsonParseError> {
1873        let start = self.index;
1874        self.consume_byte(b'{')?;
1875        let token_index = tokens.len();
1876        tokens.push(TapeToken {
1877            kind: TapeTokenKind::Object,
1878            start,
1879            end: start,
1880            parent,
1881        });
1882        self.skip_whitespace();
1883        if self.try_consume_byte(b'}') {
1884            tokens[token_index].end = self.index;
1885            return Ok(token_index);
1886        }
1887        loop {
1888            if self.peek_byte() != Some(b'"') {
1889                return match self.peek_byte() {
1890                    Some(found) => Err(JsonParseError::UnexpectedCharacter {
1891                        index: self.index,
1892                        found: found as char,
1893                    }),
1894                    None => Err(JsonParseError::UnexpectedEnd),
1895                };
1896            }
1897            self.parse_tape_string(tokens, Some(token_index), TapeTokenKind::Key)?;
1898            self.skip_whitespace();
1899            if !self.try_consume_byte(b':') {
1900                return Err(JsonParseError::ExpectedColon { index: self.index });
1901            }
1902            self.parse_tape_value(tokens, Some(token_index))?;
1903            self.skip_whitespace();
1904            if self.try_consume_byte(b'}') {
1905                tokens[token_index].end = self.index;
1906                break;
1907            }
1908            if !self.try_consume_byte(b',') {
1909                return Err(JsonParseError::ExpectedCommaOrEnd {
1910                    index: self.index,
1911                    context: "object",
1912                });
1913            }
1914            self.skip_whitespace();
1915        }
1916        Ok(token_index)
1917    }
1918
1919    fn parse_string(&mut self) -> Result<String, JsonParseError> {
1920        self.consume_byte(b'"')?;
1921        let start = self.index;
1922        loop {
1923            let Some(byte) = self.next_byte() else {
1924                return Err(JsonParseError::UnexpectedEnd);
1925            };
1926            match byte {
1927                b'"' => {
1928                    let slice = &self.input[start..self.index - 1];
1929                    return Ok(slice.to_owned());
1930                }
1931                b'\\' => {
1932                    let mut out = String::with_capacity(self.index - start + 8);
1933                    out.push_str(&self.input[start..self.index - 1]);
1934                    self.parse_escape_into(&mut out, self.index - 1)?;
1935                    return self.parse_string_slow(out);
1936                }
1937                0x00..=0x1f => {
1938                    return Err(JsonParseError::UnexpectedCharacter {
1939                        index: self.index - 1,
1940                        found: byte as char,
1941                    })
1942                }
1943                _ => {}
1944            }
1945        }
1946    }
1947
1948    fn parse_string_borrowed(&mut self) -> Result<Cow<'a, str>, JsonParseError> {
1949        self.consume_byte(b'"')?;
1950        let start = self.index;
1951        loop {
1952            let Some(byte) = self.next_byte() else {
1953                return Err(JsonParseError::UnexpectedEnd);
1954            };
1955            match byte {
1956                b'"' => {
1957                    let slice = &self.input[start..self.index - 1];
1958                    return Ok(Cow::Borrowed(slice));
1959                }
1960                b'\\' => {
1961                    let mut out = String::with_capacity(self.index - start + 8);
1962                    out.push_str(&self.input[start..self.index - 1]);
1963                    self.parse_escape_into(&mut out, self.index - 1)?;
1964                    return self.parse_string_slow_borrowed(out);
1965                }
1966                0x00..=0x1f => {
1967                    return Err(JsonParseError::UnexpectedCharacter {
1968                        index: self.index - 1,
1969                        found: byte as char,
1970                    })
1971                }
1972                _ => {}
1973            }
1974        }
1975    }
1976
1977    fn parse_tape_string(
1978        &mut self,
1979        tokens: &mut Vec<TapeToken>,
1980        parent: Option<usize>,
1981        kind: TapeTokenKind,
1982    ) -> Result<usize, JsonParseError> {
1983        let start = self.index;
1984        self.skip_string_bytes()?;
1985        let token_index = tokens.len();
1986        tokens.push(TapeToken {
1987            kind,
1988            start,
1989            end: self.index,
1990            parent,
1991        });
1992        Ok(token_index)
1993    }
1994
1995    fn skip_string_bytes(&mut self) -> Result<(), JsonParseError> {
1996        self.consume_byte(b'"')?;
1997        loop {
1998            let Some(byte) = self.next_byte() else {
1999                return Err(JsonParseError::UnexpectedEnd);
2000            };
2001            match byte {
2002                b'"' => return Ok(()),
2003                b'\\' => {
2004                    let escape_index = self.index - 1;
2005                    let escaped = self.next_byte().ok_or(JsonParseError::UnexpectedEnd)?;
2006                    match escaped {
2007                        b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {}
2008                        b'u' => {
2009                            let scalar = self.parse_hex_quad(escape_index)?;
2010                            if (0xD800..=0xDBFF).contains(&scalar) {
2011                                if self.next_byte() != Some(b'\\') || self.next_byte() != Some(b'u')
2012                                {
2013                                    return Err(JsonParseError::InvalidUnicodeScalar {
2014                                        index: escape_index,
2015                                    });
2016                                }
2017                                let low = self.parse_hex_quad(escape_index)?;
2018                                if !(0xDC00..=0xDFFF).contains(&low) {
2019                                    return Err(JsonParseError::InvalidUnicodeScalar {
2020                                        index: escape_index,
2021                                    });
2022                                }
2023                            } else if (0xDC00..=0xDFFF).contains(&scalar) {
2024                                return Err(JsonParseError::InvalidUnicodeScalar {
2025                                    index: escape_index,
2026                                });
2027                            }
2028                        }
2029                        _ => {
2030                            return Err(JsonParseError::InvalidEscape {
2031                                index: escape_index,
2032                            })
2033                        }
2034                    }
2035                }
2036                0x00..=0x1f => {
2037                    return Err(JsonParseError::UnexpectedCharacter {
2038                        index: self.index - 1,
2039                        found: byte as char,
2040                    })
2041                }
2042                _ => {}
2043            }
2044        }
2045    }
2046
2047    fn parse_string_slow(&mut self, mut out: String) -> Result<String, JsonParseError> {
2048        let mut chunk_start = self.index;
2049        loop {
2050            let Some(byte) = self.next_byte() else {
2051                return Err(JsonParseError::UnexpectedEnd);
2052            };
2053            match byte {
2054                b'"' => {
2055                    if chunk_start < self.index - 1 {
2056                        out.push_str(&self.input[chunk_start..self.index - 1]);
2057                    }
2058                    return Ok(out);
2059                }
2060                b'\\' => {
2061                    if chunk_start < self.index - 1 {
2062                        out.push_str(&self.input[chunk_start..self.index - 1]);
2063                    }
2064                    self.parse_escape_into(&mut out, self.index - 1)?;
2065                    chunk_start = self.index;
2066                }
2067                0x00..=0x1f => {
2068                    return Err(JsonParseError::UnexpectedCharacter {
2069                        index: self.index - 1,
2070                        found: byte as char,
2071                    })
2072                }
2073                _ => {}
2074            }
2075        }
2076    }
2077
2078    fn parse_string_slow_borrowed(
2079        &mut self,
2080        mut out: String,
2081    ) -> Result<Cow<'a, str>, JsonParseError> {
2082        let mut chunk_start = self.index;
2083        loop {
2084            let Some(byte) = self.next_byte() else {
2085                return Err(JsonParseError::UnexpectedEnd);
2086            };
2087            match byte {
2088                b'"' => {
2089                    if chunk_start < self.index - 1 {
2090                        out.push_str(&self.input[chunk_start..self.index - 1]);
2091                    }
2092                    return Ok(Cow::Owned(out));
2093                }
2094                b'\\' => {
2095                    if chunk_start < self.index - 1 {
2096                        out.push_str(&self.input[chunk_start..self.index - 1]);
2097                    }
2098                    self.parse_escape_into(&mut out, self.index - 1)?;
2099                    chunk_start = self.index;
2100                }
2101                0x00..=0x1f => {
2102                    return Err(JsonParseError::UnexpectedCharacter {
2103                        index: self.index - 1,
2104                        found: byte as char,
2105                    })
2106                }
2107                _ => {}
2108            }
2109        }
2110    }
2111
2112    fn parse_escape_into(
2113        &mut self,
2114        out: &mut String,
2115        escape_index: usize,
2116    ) -> Result<(), JsonParseError> {
2117        let escaped = self.next_byte().ok_or(JsonParseError::UnexpectedEnd)?;
2118        match escaped {
2119            b'"' => out.push('"'),
2120            b'\\' => out.push('\\'),
2121            b'/' => out.push('/'),
2122            b'b' => out.push('\u{0008}'),
2123            b'f' => out.push('\u{000C}'),
2124            b'n' => out.push('\n'),
2125            b'r' => out.push('\r'),
2126            b't' => out.push('\t'),
2127            b'u' => out.push(self.parse_unicode_escape(escape_index)?),
2128            _ => {
2129                return Err(JsonParseError::InvalidEscape {
2130                    index: escape_index,
2131                })
2132            }
2133        }
2134        Ok(())
2135    }
2136
2137    fn parse_unicode_escape(&mut self, index: usize) -> Result<char, JsonParseError> {
2138        let scalar = self.parse_hex_quad(index)?;
2139        if (0xD800..=0xDBFF).contains(&scalar) {
2140            if self.next_byte() != Some(b'\\') || self.next_byte() != Some(b'u') {
2141                return Err(JsonParseError::InvalidUnicodeScalar { index });
2142            }
2143            let low = self.parse_hex_quad(index)?;
2144            if !(0xDC00..=0xDFFF).contains(&low) {
2145                return Err(JsonParseError::InvalidUnicodeScalar { index });
2146            }
2147            let high = scalar - 0xD800;
2148            let low = low - 0xDC00;
2149            let combined = 0x10000 + ((high << 10) | low);
2150            char::from_u32(combined).ok_or(JsonParseError::InvalidUnicodeScalar { index })
2151        } else if (0xDC00..=0xDFFF).contains(&scalar) {
2152            Err(JsonParseError::InvalidUnicodeScalar { index })
2153        } else {
2154            char::from_u32(scalar).ok_or(JsonParseError::InvalidUnicodeScalar { index })
2155        }
2156    }
2157
2158    fn parse_hex_quad(&mut self, index: usize) -> Result<u32, JsonParseError> {
2159        let mut value = 0u32;
2160        for _ in 0..4 {
2161            let ch = self.next_byte().ok_or(JsonParseError::UnexpectedEnd)?;
2162            let digit = match ch {
2163                b'0'..=b'9' => (ch - b'0') as u32,
2164                b'a'..=b'f' => 10 + (ch - b'a') as u32,
2165                b'A'..=b'F' => 10 + (ch - b'A') as u32,
2166                _ => return Err(JsonParseError::InvalidUnicodeEscape { index }),
2167            };
2168            value = (value << 4) | digit;
2169        }
2170        Ok(value)
2171    }
2172
2173    fn parse_number(&mut self) -> Result<JsonNumber, JsonParseError> {
2174        let start = self.index;
2175        self.try_consume_byte(b'-');
2176        if self.try_consume_byte(b'0') {
2177            if matches!(self.peek_byte(), Some(b'0'..=b'9')) {
2178                return Err(JsonParseError::InvalidNumber { index: start });
2179            }
2180        } else {
2181            self.consume_digits(start)?;
2182        }
2183
2184        let mut is_float = false;
2185        if self.try_consume_byte(b'.') {
2186            is_float = true;
2187            self.consume_digits(start)?;
2188        }
2189        if matches!(self.peek_byte(), Some(b'e' | b'E')) {
2190            is_float = true;
2191            self.index += 1;
2192            if matches!(self.peek_byte(), Some(b'+' | b'-')) {
2193                self.index += 1;
2194            }
2195            self.consume_digits(start)?;
2196        }
2197
2198        let token = &self.input[start..self.index];
2199        if is_float {
2200            let value = token
2201                .parse::<f64>()
2202                .map_err(|_| JsonParseError::InvalidNumber { index: start })?;
2203            if !value.is_finite() {
2204                return Err(JsonParseError::InvalidNumber { index: start });
2205            }
2206            Ok(JsonNumber::F64(value))
2207        } else if token.starts_with('-') {
2208            let value = token
2209                .parse::<i64>()
2210                .map_err(|_| JsonParseError::InvalidNumber { index: start })?;
2211            Ok(JsonNumber::I64(value))
2212        } else {
2213            let value = token
2214                .parse::<u64>()
2215                .map_err(|_| JsonParseError::InvalidNumber { index: start })?;
2216            Ok(JsonNumber::U64(value))
2217        }
2218    }
2219
2220    fn parse_tape_number(
2221        &mut self,
2222        tokens: &mut Vec<TapeToken>,
2223        parent: Option<usize>,
2224    ) -> Result<usize, JsonParseError> {
2225        let start = self.index;
2226        let _ = self.parse_number()?;
2227        let token_index = tokens.len();
2228        tokens.push(TapeToken {
2229            kind: TapeTokenKind::Number,
2230            start,
2231            end: self.index,
2232            parent,
2233        });
2234        Ok(token_index)
2235    }
2236
2237    fn consume_digits(&mut self, index: usize) -> Result<(), JsonParseError> {
2238        let start = self.index;
2239        while matches!(self.peek_byte(), Some(b'0'..=b'9')) {
2240            self.index += 1;
2241        }
2242        if self.index == start {
2243            return Err(JsonParseError::InvalidNumber { index });
2244        }
2245        Ok(())
2246    }
2247
2248    fn consume_byte(&mut self, expected: u8) -> Result<(), JsonParseError> {
2249        match self.next_byte() {
2250            Some(found) if found == expected => Ok(()),
2251            Some(found) => Err(JsonParseError::UnexpectedCharacter {
2252                index: self.index.saturating_sub(1),
2253                found: found as char,
2254            }),
2255            None => Err(JsonParseError::UnexpectedEnd),
2256        }
2257    }
2258
2259    fn try_consume_byte(&mut self, expected: u8) -> bool {
2260        if self.peek_byte() == Some(expected) {
2261            self.index += 1;
2262            true
2263        } else {
2264            false
2265        }
2266    }
2267
2268    fn skip_whitespace(&mut self) {
2269        while matches!(self.peek_byte(), Some(b' ' | b'\n' | b'\r' | b'\t')) {
2270            self.index += 1;
2271        }
2272    }
2273
2274    fn peek_byte(&self) -> Option<u8> {
2275        self.bytes.get(self.index).copied()
2276    }
2277
2278    fn next_byte(&mut self) -> Option<u8> {
2279        let byte = self.peek_byte()?;
2280        self.index += 1;
2281        Some(byte)
2282    }
2283
2284    fn is_eof(&self) -> bool {
2285        self.index >= self.input.len()
2286    }
2287}
2288
2289#[cfg(test)]
2290mod tests {
2291    use super::*;
2292
2293    #[test]
2294    fn escapes_control_characters_and_quotes() {
2295        let escaped = escape_json_string("hello\t\"world\"\n\u{0007}");
2296        assert_eq!(escaped, "\"hello\\t\\\"world\\\"\\n\\u0007\"");
2297    }
2298
2299    #[test]
2300    fn serializes_nested_values() {
2301        let value = JsonValue::object(vec![
2302            ("name", "node-1".into()),
2303            ("ok", true.into()),
2304            (
2305                "values",
2306                JsonValue::array(vec![1u32.into(), 2u32.into(), JsonValue::Null]),
2307            ),
2308        ]);
2309        assert_eq!(
2310            value.to_json_string().unwrap(),
2311            "{\"name\":\"node-1\",\"ok\":true,\"values\":[1,2,null]}"
2312        );
2313    }
2314
2315    #[test]
2316    fn rejects_non_finite_float() {
2317        let value = JsonValue::from(f64::NAN);
2318        assert_eq!(value.to_json_string(), Err(JsonError::NonFiniteNumber));
2319    }
2320
2321    #[test]
2322    fn parses_basic_json_values() {
2323        assert_eq!(parse_json("null").unwrap(), JsonValue::Null);
2324        assert_eq!(parse_json("true").unwrap(), JsonValue::Bool(true));
2325        assert_eq!(
2326            parse_json("\"hello\"").unwrap(),
2327            JsonValue::String("hello".into())
2328        );
2329        assert_eq!(
2330            parse_json("123").unwrap(),
2331            JsonValue::Number(JsonNumber::U64(123))
2332        );
2333        assert_eq!(
2334            parse_json("-123").unwrap(),
2335            JsonValue::Number(JsonNumber::I64(-123))
2336        );
2337    }
2338
2339    #[test]
2340    fn parses_unicode_and_escapes() {
2341        let value = parse_json("\"line\\n\\u03bb\\uD83D\\uDE80\"").unwrap();
2342        assert_eq!(value, JsonValue::String("line\nλ🚀".into()));
2343    }
2344
2345    #[test]
2346    fn borrowed_parse_avoids_allocating_plain_strings() {
2347        let value = parse_json_borrowed("{\"name\":\"hello\",\"n\":1}").unwrap();
2348        match value {
2349            BorrowedJsonValue::Object(entries) => {
2350                assert!(matches!(entries[0].0, Cow::Borrowed(_)));
2351                assert!(matches!(
2352                    entries[0].1,
2353                    BorrowedJsonValue::String(Cow::Borrowed(_))
2354                ));
2355            }
2356            other => panic!("unexpected value: {other:?}"),
2357        }
2358    }
2359
2360    #[test]
2361    fn borrowed_parse_allocates_when_unescaping_is_needed() {
2362        let value = parse_json_borrowed("\"line\\nvalue\"").unwrap();
2363        match value {
2364            BorrowedJsonValue::String(Cow::Owned(text)) => assert_eq!(text, "line\nvalue"),
2365            other => panic!("unexpected value: {other:?}"),
2366        }
2367    }
2368
2369    #[test]
2370    fn compiled_schema_serializes_expected_shape() {
2371        let schema = CompiledObjectSchema::new(&["id", "name", "enabled"]);
2372        let values = [
2373            JsonValue::from(7u64),
2374            JsonValue::from("node-7"),
2375            JsonValue::from(true),
2376        ];
2377        let json = schema.to_json_string(values.iter()).unwrap();
2378        assert_eq!(json, "{\"id\":7,\"name\":\"node-7\",\"enabled\":true}");
2379    }
2380
2381    #[test]
2382    fn compiled_row_schema_serializes_array_of_objects() {
2383        let schema = CompiledRowSchema::new(&["id", "name"]);
2384        let row1 = [JsonValue::from(1u64), JsonValue::from("a")];
2385        let row2 = [JsonValue::from(2u64), JsonValue::from("b")];
2386        let json = schema.to_json_string([row1.iter(), row2.iter()]).unwrap();
2387        assert_eq!(json, r#"[{"id":1,"name":"a"},{"id":2,"name":"b"}]"#);
2388    }
2389
2390    #[test]
2391    fn tape_parse_records_structure_tokens() {
2392        let tape = parse_json_tape(r#"{"a":[1,"x"],"b":true}"#).unwrap();
2393        assert_eq!(tape.tokens[0].kind, TapeTokenKind::Object);
2394        assert_eq!(tape.tokens[1].kind, TapeTokenKind::Key);
2395        assert_eq!(tape.tokens[2].kind, TapeTokenKind::Array);
2396        assert_eq!(tape.tokens[3].kind, TapeTokenKind::Number);
2397        assert_eq!(tape.tokens[4].kind, TapeTokenKind::String);
2398        assert_eq!(tape.tokens[5].kind, TapeTokenKind::Key);
2399        assert_eq!(tape.tokens[6].kind, TapeTokenKind::Bool);
2400    }
2401
2402    #[test]
2403    fn tape_object_lookup_finds_child_values() {
2404        let input = r#"{"name":"hello","nested":{"x":1},"flag":true}"#;
2405        let tape = parse_json_tape(input).unwrap();
2406        let root = tape.root(input).unwrap();
2407        let name = root.get("name").unwrap();
2408        assert_eq!(name.kind(), TapeTokenKind::String);
2409        assert_eq!(name.as_str(), Some("hello"));
2410        let nested = root.get("nested").unwrap();
2411        assert_eq!(nested.kind(), TapeTokenKind::Object);
2412        assert!(root.get("missing").is_none());
2413    }
2414
2415    #[test]
2416    fn tape_object_index_lookup_finds_child_values() {
2417        let input = r#"{"name":"hello","nested":{"x":1},"flag":true}"#;
2418        let tape = parse_json_tape(input).unwrap();
2419        let root = tape.root(input).unwrap();
2420        let index = root.build_object_index().unwrap();
2421        let flag = index.get(root, "flag").unwrap();
2422        assert_eq!(flag.kind(), TapeTokenKind::Bool);
2423        assert!(index.get(root, "missing").is_none());
2424    }
2425
2426    #[test]
2427    fn indexed_tape_object_compiled_lookup_finds_child_values() {
2428        let input = r#"{"name":"hello","nested":{"x":1},"flag":true}"#;
2429        let tape = parse_json_tape(input).unwrap();
2430        let root = tape.root(input).unwrap();
2431        let index = root.build_object_index().unwrap();
2432        let indexed = root.with_index(&index);
2433        let keys = CompiledTapeKeys::new(&["name", "flag", "missing"]);
2434        let got = indexed
2435            .get_compiled_many(&keys)
2436            .map(|value| value.map(|value| value.kind()))
2437            .collect::<Vec<_>>();
2438        assert_eq!(got, vec![Some(TapeTokenKind::String), Some(TapeTokenKind::Bool), None]);
2439    }
2440
2441    #[test]
2442    fn serde_style_convenience_api_works() {
2443        let value = from_str(r#"{"ok":true,"n":7,"items":[1,2,3],"msg":"hello"}"#).unwrap();
2444        assert!(value.is_object());
2445        assert_eq!(value["ok"].as_bool(), Some(true));
2446        assert_eq!(value["n"].as_i64(), Some(7));
2447        assert_eq!(value["msg"].as_str(), Some("hello"));
2448        assert_eq!(value["items"][1].as_u64(), Some(2));
2449        assert!(value["missing"].is_null());
2450        assert_eq!(to_string(&value).unwrap(), r#"{"ok":true,"n":7,"items":[1,2,3],"msg":"hello"}"#);
2451        assert_eq!(from_slice(br#"[1,true,"x"]"#).unwrap()[2].as_str(), Some("x"));
2452        assert_eq!(to_vec(&value).unwrap(), value.to_json_string().unwrap().into_bytes());
2453    }
2454
2455    #[test]
2456    fn json_macro_builds_values() {
2457        let value = json!({"ok": true, "items": [1, 2, null], "msg": "x"});
2458        assert_eq!(value["ok"].as_bool(), Some(true));
2459        assert_eq!(value["items"][0].as_u64(), Some(1));
2460        assert!(value["items"][2].is_null());
2461        assert_eq!(value["msg"].as_str(), Some("x"));
2462    }
2463
2464    #[test]
2465    fn from_slice_rejects_invalid_utf8() {
2466        assert!(matches!(from_slice(&[0xff]), Err(JsonParseError::InvalidUtf8)));
2467    }
2468
2469    #[test]
2470    fn pointer_take_and_pretty_helpers_work() {
2471        let mut value = from_str(r#"{"a":{"b":[10,20,{"~key/":"x"}]}}"#).unwrap();
2472        assert_eq!(value.pointer("/a/b/1").and_then(JsonValue::as_u64), Some(20));
2473        assert_eq!(value.pointer("/a/b/2/~0key~1").and_then(JsonValue::as_str), Some("x"));
2474        *value.pointer_mut("/a/b/0").unwrap() = JsonValue::from(99u64);
2475        assert_eq!(value.pointer("/a/b/0").and_then(JsonValue::as_u64), Some(99));
2476
2477        let taken = value.pointer_mut("/a/b/2").unwrap().take();
2478        assert!(value.pointer("/a/b/2").unwrap().is_null());
2479        assert_eq!(taken["~key/"].as_str(), Some("x"));
2480
2481        let pretty = to_string_pretty(&value).unwrap();
2482        assert!(pretty.contains("\"a\": {"));
2483        let mut out = Vec::new();
2484        to_writer_pretty(&mut out, &value).unwrap();
2485        assert_eq!(String::from_utf8(out).unwrap(), pretty);
2486    }
2487
2488    #[test]
2489    fn reader_writer_and_collection_helpers_work() {
2490        let value = from_reader(std::io::Cursor::new(br#"{"a":1,"b":[true,false]}"# as &[u8])).unwrap();
2491        assert_eq!(value["a"].as_u64(), Some(1));
2492        assert_eq!(value["b"].len(), 2);
2493        assert_eq!(value["b"].get_index(1).and_then(JsonValue::as_bool), Some(false));
2494
2495        let mut out = Vec::new();
2496        to_writer(&mut out, &value).unwrap();
2497        assert_eq!(String::from_utf8(out).unwrap(), value.to_json_string().unwrap());
2498
2499        let object = JsonValue::from_iter([("x", 1u64), ("y", 2u64)]);
2500        assert_eq!(object["x"].as_u64(), Some(1));
2501        let array = JsonValue::from_iter([1u64, 2u64, 3u64]);
2502        assert_eq!(array.get_index(2).and_then(JsonValue::as_u64), Some(3));
2503    }
2504
2505    #[test]
2506    fn generic_get_and_get_mut_index_parity_work() {
2507        let mut value = json!({"obj": {"x": 1}, "arr": [10, 20, 30]});
2508        let key = String::from("obj");
2509        assert_eq!(value.get("obj").and_then(|v| v.get("x")).and_then(JsonValue::as_u64), Some(1));
2510        assert_eq!(value.get(&key).and_then(|v| v.get("x")).and_then(JsonValue::as_u64), Some(1));
2511        assert_eq!(value.get("arr").and_then(|v| v.get(1)).and_then(JsonValue::as_u64), Some(20));
2512        *value.get_mut("arr").unwrap().get_mut(2).unwrap() = JsonValue::from(99u64);
2513        assert_eq!(value["arr"][2].as_u64(), Some(99));
2514    }
2515
2516    #[test]
2517    fn number_and_mut_index_parity_helpers_work() {
2518        let int = JsonValue::from(7i64);
2519        assert!(int.is_i64());
2520        assert!(!int.is_u64());
2521        assert!(!int.is_f64());
2522        assert_eq!(int.as_number().and_then(JsonNumber::as_i64), Some(7));
2523
2524        let float = JsonValue::Number(JsonNumber::from_f64(2.5).unwrap());
2525        assert!(float.is_f64());
2526        assert_eq!(float.as_f64(), Some(2.5));
2527        assert_eq!(JsonValue::Null.as_null(), Some(()));
2528
2529        let mut value = JsonValue::Null;
2530        value["a"]["b"]["c"] = JsonValue::from(true);
2531        assert_eq!(value.pointer("/a/b/c").and_then(JsonValue::as_bool), Some(true));
2532
2533        value["arr"] = json!([1, 2, 3]);
2534        value["arr"][1] = JsonValue::from(9u64);
2535        assert_eq!(value.pointer("/arr/1").and_then(JsonValue::as_u64), Some(9));
2536    }
2537
2538    #[test]
2539    fn rejects_invalid_json_inputs() {
2540        assert!(matches!(
2541            parse_json("{"),
2542            Err(JsonParseError::UnexpectedEnd)
2543        ));
2544        assert!(matches!(
2545            parse_json("{\"a\" 1}"),
2546            Err(JsonParseError::ExpectedColon { .. })
2547        ));
2548        assert!(matches!(
2549            parse_json("[1 2]"),
2550            Err(JsonParseError::ExpectedCommaOrEnd {
2551                context: "array",
2552                ..
2553            })
2554        ));
2555        assert!(matches!(
2556            parse_json("{\"a\":1 trailing"),
2557            Err(JsonParseError::ExpectedCommaOrEnd {
2558                context: "object",
2559                ..
2560            })
2561        ));
2562        assert!(matches!(
2563            parse_json("00"),
2564            Err(JsonParseError::InvalidNumber { .. })
2565        ));
2566    }
2567
2568    #[test]
2569    fn roundtrips_specific_structures() {
2570        let values = [
2571            JsonValue::Null,
2572            JsonValue::Bool(false),
2573            JsonValue::String("tab\tquote\"slash\\snowman☃".into()),
2574            JsonValue::Number(JsonNumber::I64(-9_223_372_036_854_775_808)),
2575            JsonValue::Number(JsonNumber::U64(u64::MAX)),
2576            JsonValue::Number(JsonNumber::F64(12345.125)),
2577            JsonValue::Array(vec![
2578                JsonValue::Bool(true),
2579                JsonValue::String("nested".into()),
2580                JsonValue::Object(vec![("x".into(), 1u64.into())]),
2581            ]),
2582        ];
2583        for value in values {
2584            let text = value.to_json_string().unwrap();
2585            let reparsed = parse_json(&text).unwrap();
2586            assert_json_equivalent(&value, &reparsed);
2587        }
2588    }
2589
2590    #[test]
2591    fn deterministic_fuzz_roundtrip_strings_and_values() {
2592        let mut rng = Rng::new(0x5eed_1234_5678_9abc);
2593        for _ in 0..2_000 {
2594            let input = random_string(&mut rng, 48);
2595            let escaped = escape_json_string(&input);
2596            let parsed = parse_json(&escaped).unwrap();
2597            assert_eq!(parsed, JsonValue::String(input));
2598        }
2599
2600        for _ in 0..1_000 {
2601            let value = random_json_value(&mut rng, 0, 4);
2602            let text = value.to_json_string().unwrap();
2603            let reparsed = parse_json(&text).unwrap();
2604            assert_json_equivalent(&value, &reparsed);
2605        }
2606    }
2607
2608    fn assert_json_equivalent(expected: &JsonValue, actual: &JsonValue) {
2609        match (expected, actual) {
2610            (JsonValue::Null, JsonValue::Null) => {}
2611            (JsonValue::Bool(a), JsonValue::Bool(b)) => assert_eq!(a, b),
2612            (JsonValue::String(a), JsonValue::String(b)) => assert_eq!(a, b),
2613            (JsonValue::Number(a), JsonValue::Number(b)) => assert_numbers_equivalent(a, b),
2614            (JsonValue::Array(a), JsonValue::Array(b)) => {
2615                assert_eq!(a.len(), b.len());
2616                for (left, right) in a.iter().zip(b.iter()) {
2617                    assert_json_equivalent(left, right);
2618                }
2619            }
2620            (JsonValue::Object(a), JsonValue::Object(b)) => {
2621                assert_eq!(a.len(), b.len());
2622                for ((left_key, left_value), (right_key, right_value)) in a.iter().zip(b.iter()) {
2623                    assert_eq!(left_key, right_key);
2624                    assert_json_equivalent(left_value, right_value);
2625                }
2626            }
2627            _ => panic!("json values differ: expected {expected:?}, actual {actual:?}"),
2628        }
2629    }
2630
2631    fn assert_numbers_equivalent(expected: &JsonNumber, actual: &JsonNumber) {
2632        match (expected, actual) {
2633            (JsonNumber::I64(a), JsonNumber::I64(b)) => assert_eq!(a, b),
2634            (JsonNumber::U64(a), JsonNumber::U64(b)) => assert_eq!(a, b),
2635            (JsonNumber::F64(a), JsonNumber::F64(b)) => assert_eq!(a.to_bits(), b.to_bits()),
2636            (JsonNumber::I64(a), JsonNumber::U64(b)) if *a >= 0 => assert_eq!(*a as u64, *b),
2637            (JsonNumber::U64(a), JsonNumber::I64(b)) if *b >= 0 => assert_eq!(*a, *b as u64),
2638            (JsonNumber::I64(a), JsonNumber::F64(b)) => assert_eq!(*a as f64, *b),
2639            (JsonNumber::U64(a), JsonNumber::F64(b)) => assert_eq!(*a as f64, *b),
2640            (JsonNumber::F64(a), JsonNumber::I64(b)) => assert_eq!(*a, *b as f64),
2641            (JsonNumber::F64(a), JsonNumber::U64(b)) => assert_eq!(*a, *b as f64),
2642            (left, right) => panic!("json numbers differ: expected {left:?}, actual {right:?}"),
2643        }
2644    }
2645
2646    #[derive(Clone, Debug)]
2647    struct Rng {
2648        state: u64,
2649    }
2650
2651    impl Rng {
2652        fn new(seed: u64) -> Self {
2653            Self { state: seed }
2654        }
2655
2656        fn next_u64(&mut self) -> u64 {
2657            self.state = self
2658                .state
2659                .wrapping_mul(6364136223846793005)
2660                .wrapping_add(1442695040888963407);
2661            self.state
2662        }
2663
2664        fn choose(&mut self, upper_exclusive: usize) -> usize {
2665            (self.next_u64() % upper_exclusive as u64) as usize
2666        }
2667
2668        fn bool(&mut self) -> bool {
2669            (self.next_u64() & 1) == 1
2670        }
2671    }
2672
2673    fn random_string(rng: &mut Rng, max_len: usize) -> String {
2674        let len = rng.choose(max_len + 1);
2675        let mut out = String::new();
2676        for _ in 0..len {
2677            let ch = match rng.choose(12) {
2678                0 => '"',
2679                1 => '\\',
2680                2 => '\n',
2681                3 => '\r',
2682                4 => '\t',
2683                5 => '\u{0007}',
2684                6 => 'λ',
2685                7 => '🚀',
2686                8 => '☃',
2687                _ => (b'a' + rng.choose(26) as u8) as char,
2688            };
2689            out.push(ch);
2690        }
2691        out
2692    }
2693
2694    fn random_json_value(rng: &mut Rng, depth: usize, max_depth: usize) -> JsonValue {
2695        if depth >= max_depth {
2696            return random_leaf(rng);
2697        }
2698        match rng.choose(7) {
2699            0 | 1 | 2 | 3 => random_leaf(rng),
2700            4 => {
2701                let len = rng.choose(5);
2702                let mut values = Vec::with_capacity(len);
2703                for _ in 0..len {
2704                    values.push(random_json_value(rng, depth + 1, max_depth));
2705                }
2706                JsonValue::Array(values)
2707            }
2708            _ => {
2709                let len = rng.choose(5);
2710                let mut entries = Vec::with_capacity(len);
2711                for index in 0..len {
2712                    entries.push((
2713                        format!("k{depth}_{index}_{}", random_string(rng, 6)),
2714                        random_json_value(rng, depth + 1, max_depth),
2715                    ));
2716                }
2717                JsonValue::Object(entries)
2718            }
2719        }
2720    }
2721
2722    fn random_leaf(rng: &mut Rng) -> JsonValue {
2723        match rng.choose(6) {
2724            0 => JsonValue::Null,
2725            1 => JsonValue::Bool(rng.bool()),
2726            2 => JsonValue::String(random_string(rng, 24)),
2727            3 => JsonValue::Number(JsonNumber::I64(
2728                (rng.next_u64() >> 1) as i64 * if rng.bool() { 1 } else { -1 },
2729            )),
2730            4 => JsonValue::Number(JsonNumber::U64(rng.next_u64())),
2731            _ => {
2732                let mantissa = (rng.next_u64() % 1_000_000) as f64 / 1000.0;
2733                let sign = if rng.bool() { 1.0 } else { -1.0 };
2734                JsonValue::Number(JsonNumber::F64(sign * mantissa))
2735            }
2736        }
2737    }
2738}