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