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