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