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