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