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