1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![doc = include_str!("../README.md")]
3#![deny(missing_docs)]
4#![no_std]
5
6#[cfg(feature = "alloc")]
7extern crate alloc;
8
9mod io;
10mod stack;
11mod string;
12mod number;
13
14pub(crate) use io::*;
15pub use io::BytesLike;
16pub use stack::*;
17use string::*;
18
19#[derive(Debug)]
21pub enum JsonError<'bytes, B: BytesLike<'bytes>, S: Stack> {
22 InternalError,
24 BytesError(B::Error),
26 StackError(S::Error),
28 ReusedDeserializer,
30 InvalidKey,
32 InvalidKeyValueDelimiter,
34 InvalidValue,
36 TrailingComma,
38 MismatchedDelimiter,
40 TypeError,
42}
43impl<'bytes, B: BytesLike<'bytes>, S: Stack> Clone for JsonError<'bytes, B, S> {
44 #[inline(always)]
45 fn clone(&self) -> Self {
46 *self
47 }
48}
49impl<'bytes, B: BytesLike<'bytes>, S: Stack> Copy for JsonError<'bytes, B, S> {}
50
51#[inline(always)]
53pub fn as_bool<'bytes, B: BytesLike<'bytes>, S: Stack>(
54 bytes: &B,
55) -> Result<bool, JsonError<'bytes, B, S>> {
56 let first = bytes.peek(0).map_err(JsonError::BytesError)?;
57 if !matches!(first, b't' | b'f') {
59 Err(JsonError::TypeError)?;
60 }
61 let second = bytes.peek(1).map_err(JsonError::BytesError)?;
62 let third = bytes.peek(2).map_err(JsonError::BytesError)?;
63 let fourth = bytes.peek(3).map_err(JsonError::BytesError)?;
64 let fifth = bytes.peek(4).map_err(JsonError::BytesError)?;
65
66 let is_true = (first, second, third, fourth) == (b't', b'r', b'u', b'e');
67 let is_false = (first, second, third, fourth, fifth) == (b'f', b'a', b'l', b's', b'e');
68
69 if !(is_true || is_false) {
70 Err(JsonError::TypeError)?;
71 }
72
73 Ok(is_true)
74}
75
76#[inline(always)]
78pub fn is_null<'bytes, B: BytesLike<'bytes>, S: Stack>(
79 bytes: &B,
80) -> Result<bool, JsonError<'bytes, B, S>> {
81 let first = bytes.peek(0).map_err(JsonError::BytesError)?;
82 if first != b'n' {
83 return Ok(false);
84 }
85 let second = bytes.peek(1).map_err(JsonError::BytesError)?;
86 let third = bytes.peek(2).map_err(JsonError::BytesError)?;
87 let fourth = bytes.peek(3).map_err(JsonError::BytesError)?;
88
89 if (second, third, fourth) != (b'u', b'l', b'l') {
90 Err(JsonError::InvalidValue)?;
91 }
92 Ok(true)
93}
94
95#[inline(always)]
97fn advance_whitespace<'bytes, B: BytesLike<'bytes>, S: Stack>(
98 bytes: &mut B,
99) -> Result<(), JsonError<'bytes, B, S>> {
100 loop {
101 let next = bytes.peek(0).map_err(JsonError::BytesError)?;
102 if !matches!(next, b'\x20' | b'\x09' | b'\x0A' | b'\x0D') {
104 break;
105 }
106 bytes.advance(1).map_err(JsonError::BytesError)?;
107 }
108 Ok(())
109}
110
111fn advance_past_comma_or_to_close<'bytes, B: BytesLike<'bytes>, S: Stack>(
113 bytes: &mut B,
114) -> Result<(), JsonError<'bytes, B, S>> {
115 advance_whitespace(bytes)?;
116 match bytes.peek(0).map_err(JsonError::BytesError)? {
117 b',' => {
118 bytes.advance(1).map_err(JsonError::BytesError)?;
119 advance_whitespace(bytes)?;
120 if matches!(bytes.peek(0).map_err(JsonError::BytesError)?, b']' | b'}') {
121 Err(JsonError::TrailingComma)?;
122 }
123 }
124 b']' | b'}' => {}
125 _ => Err(JsonError::InvalidValue)?,
126 }
127 Ok(())
128}
129
130enum SingleStepObjectResult<'bytes, B: BytesLike<'bytes>> {
132 Field {
134 key: String<'bytes, B>,
136 },
137 Closed,
139}
140
141enum SingleStepArrayResult {
143 Value,
145 Closed,
147}
148
149enum SingleStepUnknownResult<'bytes, B: BytesLike<'bytes>> {
151 ObjectOpened,
153 ArrayOpened,
155 String(String<'bytes, B>),
157 Advanced,
159}
160
161enum SingleStepResult<'bytes, B: BytesLike<'bytes>> {
163 Object(SingleStepObjectResult<'bytes, B>),
165 Array(SingleStepArrayResult),
167 Unknown(SingleStepUnknownResult<'bytes, B>),
169}
170
171fn single_step<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack>(
176 bytes: &'parent mut B,
177 stack: &'parent mut S,
178) -> Result<SingleStepResult<'bytes, B>, JsonError<'bytes, B, S>> {
179 match stack.peek().ok_or(JsonError::InternalError)? {
180 State::Object => {
181 let next = bytes.read_byte().map_err(JsonError::BytesError)?;
182
183 if next == b'}' {
185 stack.pop().ok_or(JsonError::InternalError)?;
186
187 if stack.depth() != 0 {
189 advance_past_comma_or_to_close(bytes)?;
190 }
191
192 return Ok(SingleStepResult::Object(SingleStepObjectResult::Closed));
193 }
194
195 if next != b'"' {
197 Err(JsonError::InvalidKey)?;
198 }
199 let key = read_string(bytes)?;
200
201 advance_whitespace::<_, S>(bytes)?;
203 if bytes.read_byte().map_err(JsonError::BytesError)? != b':' {
204 Err(JsonError::InvalidKeyValueDelimiter)?;
205 }
206
207 advance_whitespace::<_, S>(bytes)?;
209 stack.push(State::Unknown).map_err(JsonError::StackError)?;
210 Ok(SingleStepResult::Object(SingleStepObjectResult::Field { key }))
211 }
212 State::Array => {
213 if bytes.peek(0).map_err(JsonError::BytesError)? == b']' {
215 stack.pop().ok_or(JsonError::InternalError)?;
216 bytes.advance(1).map_err(JsonError::BytesError)?;
217
218 if stack.depth() != 0 {
220 advance_past_comma_or_to_close(bytes)?;
221 }
222
223 return Ok(SingleStepResult::Array(SingleStepArrayResult::Closed));
224 }
225
226 stack.push(State::Unknown).map_err(JsonError::StackError)?;
228 Ok(SingleStepResult::Array(SingleStepArrayResult::Value))
229 }
230 State::Unknown => {
231 stack.pop().ok_or(JsonError::InternalError)?;
232
233 let mut result = SingleStepResult::Unknown(SingleStepUnknownResult::Advanced);
234 match bytes.peek(0).map_err(JsonError::BytesError)? {
235 b'{' => {
237 bytes.advance(1).map_err(JsonError::BytesError)?;
238 advance_whitespace(bytes)?;
239 stack.push(State::Object).map_err(JsonError::StackError)?;
240 return Ok(SingleStepResult::Unknown(SingleStepUnknownResult::ObjectOpened));
241 }
242 b'[' => {
244 bytes.advance(1).map_err(JsonError::BytesError)?;
245 advance_whitespace(bytes)?;
246 stack.push(State::Array).map_err(JsonError::StackError)?;
247 return Ok(SingleStepResult::Unknown(SingleStepUnknownResult::ArrayOpened));
248 }
249 b'"' => {
251 bytes.advance(1).map_err(JsonError::BytesError)?;
252 result = SingleStepResult::Unknown(SingleStepUnknownResult::String(read_string(bytes)?));
254 }
255 _ => {
257 let is_number = match number::is_number_str(bytes) {
259 Ok(len) => Some(len),
260 Err(JsonError::TypeError) => None,
261 Err(e) => Err(e)?,
262 };
263 let is_bool = match as_bool(bytes) {
264 Ok(value) => Some(if value { 4 } else { 5 }),
265 Err(JsonError::TypeError) => None,
266 Err(e) => Err(e)?,
267 };
268 let is_null = match is_null(bytes) {
269 Ok(is_null) => {
270 if is_null {
271 Some(4)
272 } else {
273 None
274 }
275 }
276 Err(e) => Err(e)?,
277 };
278
279 if let Some(len) = is_number.or(is_bool).or(is_null) {
280 bytes.advance(len).map_err(JsonError::BytesError)?;
281 } else {
282 Err(JsonError::InvalidValue)?;
283 }
284 }
285 }
286
287 advance_past_comma_or_to_close(bytes)?;
289
290 Ok(result)
291 }
292 }
293}
294
295pub struct Deserializer<'bytes, B: BytesLike<'bytes>, S: Stack> {
297 bytes: B,
298 stack: S,
299 error: Option<JsonError<'bytes, B, S>>,
305}
306
307pub struct Value<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> {
310 deserializer: Option<&'parent mut Deserializer<'bytes, B, S>>,
311}
312
313impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> Drop for Value<'bytes, 'parent, B, S> {
314 fn drop(&mut self) {
315 if let Some(deserializer) = self.deserializer.take() {
321 if deserializer.error.is_some() {
322 return;
323 }
324
325 let Some(current) = deserializer.stack.peek() else {
326 deserializer.error = Some(JsonError::InternalError);
327 return;
328 };
329
330 let mut depth = match current {
331 State::Object | State::Array => 1,
332 State::Unknown => {
333 let step = match single_step(&mut deserializer.bytes, &mut deserializer.stack) {
334 Ok(SingleStepResult::Unknown(step)) => step,
335 Ok(_) => {
336 deserializer.error = Some(JsonError::InternalError);
337 return;
338 }
339 Err(e) => {
340 deserializer.error = Some(e);
341 return;
342 }
343 };
344 match step {
345 SingleStepUnknownResult::String(_) | SingleStepUnknownResult::Advanced => return,
347 SingleStepUnknownResult::ObjectOpened | SingleStepUnknownResult::ArrayOpened => 1,
349 }
350 }
351 };
352
353 while depth != 0 {
355 let step = match single_step(&mut deserializer.bytes, &mut deserializer.stack) {
356 Ok(step) => step,
357 Err(e) => {
358 deserializer.error = Some(e);
359 return;
360 }
361 };
362 match step {
363 SingleStepResult::Object(SingleStepObjectResult::Closed) |
364 SingleStepResult::Array(SingleStepArrayResult::Closed) => depth -= 1,
365 SingleStepResult::Unknown(
366 SingleStepUnknownResult::ObjectOpened | SingleStepUnknownResult::ArrayOpened,
367 ) => depth += 1,
368 _ => {}
369 }
370 }
371 }
372 }
373}
374
375impl<'bytes, B: BytesLike<'bytes>, S: Stack> Deserializer<'bytes, B, S> {
376 pub fn new(mut bytes: B) -> Result<Self, JsonError<'bytes, B, S>> {
378 advance_whitespace(&mut bytes)?;
379
380 let mut stack = S::empty();
381 stack.push(State::Unknown).map_err(JsonError::StackError)?;
382
383 Ok(Deserializer { bytes, stack, error: None })
384 }
385
386 #[inline(always)]
393 pub fn value(&mut self) -> Result<Value<'bytes, '_, B, S>, JsonError<'bytes, B, S>> {
394 if self.stack.depth() != 1 {
395 Err(JsonError::ReusedDeserializer)?;
396 }
397 let result = Value { deserializer: Some(self) };
398 if !(result.is_object()? || result.is_array()?) {
399 Err(JsonError::TypeError)?;
400 }
401 Ok(result)
402 }
403}
404
405pub struct FieldIterator<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> {
407 deserializer: &'parent mut Deserializer<'bytes, B, S>,
408 done: bool,
409}
410
411impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> Drop
413 for FieldIterator<'bytes, 'parent, B, S>
414{
415 #[inline(always)]
416 fn drop(&mut self) {
417 if self.deserializer.error.is_some() {
418 return;
419 }
420
421 loop {
422 let Some(next) = self.next() else { break };
423 let next = next.map(|_| ());
424 match next {
425 Ok(()) => {}
426 Err(e) => {
427 self.deserializer.error = Some(e);
428 break;
429 }
430 }
431 }
432 }
433}
434
435impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> FieldIterator<'bytes, 'parent, B, S> {
436 #[allow(clippy::type_complexity, clippy::should_implement_trait)]
455 pub fn next(
456 &mut self,
457 ) -> Option<
458 Result<
459 (
460 impl use<'bytes, B, S> + Iterator<Item = Result<char, JsonError<'bytes, B, S>>>,
461 Value<'bytes, '_, B, S>,
462 ),
463 JsonError<'bytes, B, S>,
464 >,
465 > {
466 if let Some(err) = self.deserializer.error {
467 return Some(Err(err));
468 }
469
470 if self.done {
471 None?;
472 }
473
474 loop {
475 let result = match single_step(&mut self.deserializer.bytes, &mut self.deserializer.stack) {
476 Ok(SingleStepResult::Object(result)) => result,
477 Ok(_) => break Some(Err(JsonError::InternalError)),
478 Err(e) => break Some(Err(e)),
479 };
480 match result {
481 SingleStepObjectResult::Field { key } => {
482 break Some(Ok((
483 UnescapeString::from(key),
484 Value { deserializer: Some(self.deserializer) },
485 )))
486 }
487 SingleStepObjectResult::Closed => {
488 self.done = true;
489 None?
490 }
491 }
492 }
493 }
494}
495
496pub struct ArrayIterator<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> {
498 deserializer: &'parent mut Deserializer<'bytes, B, S>,
499 done: bool,
500}
501
502impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> Drop
504 for ArrayIterator<'bytes, 'parent, B, S>
505{
506 #[inline(always)]
507 fn drop(&mut self) {
508 if self.deserializer.error.is_some() {
509 return;
510 }
511
512 loop {
513 let Some(next) = self.next() else { break };
514 let next = next.map(|_| ());
515 match next {
516 Ok(()) => {}
517 Err(e) => {
518 self.deserializer.error = Some(e);
519 break;
520 }
521 }
522 }
523 }
524}
525
526impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> ArrayIterator<'bytes, 'parent, B, S> {
527 #[allow(clippy::should_implement_trait)]
539 pub fn next(&mut self) -> Option<Result<Value<'bytes, '_, B, S>, JsonError<'bytes, B, S>>> {
540 if let Some(err) = self.deserializer.error {
541 return Some(Err(err));
542 }
543
544 if self.done {
545 None?;
546 }
547
548 loop {
549 let result = match single_step(&mut self.deserializer.bytes, &mut self.deserializer.stack) {
550 Ok(SingleStepResult::Array(result)) => result,
551 Ok(_) => break Some(Err(JsonError::InternalError)),
552 Err(e) => break Some(Err(e)),
553 };
554 match result {
555 SingleStepArrayResult::Value => {
556 break Some(Ok(Value { deserializer: Some(self.deserializer) }))
557 }
558 SingleStepArrayResult::Closed => {
559 self.done = true;
560 None?
561 }
562 }
563 }
564 }
565}
566
567impl<'bytes, 'parent, B: BytesLike<'bytes>, S: Stack> Value<'bytes, 'parent, B, S> {
568 #[inline(always)]
570 pub fn is_object(&self) -> Result<bool, JsonError<'bytes, B, S>> {
571 Ok(
572 self
573 .deserializer
574 .as_ref()
575 .ok_or(JsonError::InternalError)?
576 .bytes
577 .peek(0)
578 .map_err(JsonError::BytesError)? ==
579 b'{',
580 )
581 }
582
583 pub fn fields(mut self) -> Result<FieldIterator<'bytes, 'parent, B, S>, JsonError<'bytes, B, S>> {
587 let deserializer = self.deserializer.take().ok_or(JsonError::InternalError)?;
588 if let Some(err) = deserializer.error {
589 Err(err)?;
590 }
591
592 match single_step(&mut deserializer.bytes, &mut deserializer.stack)? {
593 SingleStepResult::Unknown(SingleStepUnknownResult::ObjectOpened) => {
594 Ok(FieldIterator { deserializer, done: false })
595 }
596 _ => Err(JsonError::TypeError),
597 }
598 }
599
600 #[inline(always)]
602 pub fn is_array(&self) -> Result<bool, JsonError<'bytes, B, S>> {
603 Ok(
604 self
605 .deserializer
606 .as_ref()
607 .ok_or(JsonError::InternalError)?
608 .bytes
609 .peek(0)
610 .map_err(JsonError::BytesError)? ==
611 b'[',
612 )
613 }
614
615 pub fn iterate(
617 mut self,
618 ) -> Result<ArrayIterator<'bytes, 'parent, B, S>, JsonError<'bytes, B, S>> {
619 let deserializer = self.deserializer.take().ok_or(JsonError::InternalError)?;
620 if let Some(err) = deserializer.error {
621 Err(err)?;
622 }
623
624 match single_step(&mut deserializer.bytes, &mut deserializer.stack)? {
625 SingleStepResult::Unknown(SingleStepUnknownResult::ArrayOpened) => {
626 Ok(ArrayIterator { deserializer, done: false })
627 }
628 _ => Err(JsonError::TypeError),
629 }
630 }
631
632 #[inline(always)]
634 pub fn is_str(&self) -> Result<bool, JsonError<'bytes, B, S>> {
635 Ok(
636 self
637 .deserializer
638 .as_ref()
639 .ok_or(JsonError::InternalError)?
640 .bytes
641 .peek(0)
642 .map_err(JsonError::BytesError)? ==
643 b'"',
644 )
645 }
646
647 #[inline(always)]
657 pub fn to_str(
658 mut self,
659 ) -> Result<
660 impl use<'bytes, B, S> + Iterator<Item = Result<char, JsonError<'bytes, B, S>>>,
661 JsonError<'bytes, B, S>,
662 > {
663 let deserializer = self.deserializer.take().ok_or(JsonError::InternalError)?;
664 match single_step(&mut deserializer.bytes, &mut deserializer.stack)? {
665 SingleStepResult::Unknown(SingleStepUnknownResult::String(str)) => {
666 Ok(UnescapeString::from(str))
667 }
668 _ => Err(JsonError::TypeError),
669 }
670 }
671
672 #[inline(always)]
679 pub fn as_i64(&self) -> Result<i64, JsonError<'bytes, B, S>> {
680 let bytes = &self.deserializer.as_ref().ok_or(JsonError::InternalError)?.bytes;
681
682 const MAX_I64_LEN: usize = 20;
684 let len = number::is_number_str(bytes)?;
685 if len > MAX_I64_LEN {
686 Err(JsonError::TypeError)?;
687 }
688
689 let mut str = [0; MAX_I64_LEN];
690 #[allow(clippy::needless_range_loop)]
691 for i in 0 .. len {
692 let byte = bytes.peek(i).map_err(JsonError::BytesError)?;
693 if matches!(byte, b'.' | b'e' | b'E') {
694 Err(JsonError::TypeError)?;
695 }
696 str[i] = byte;
697 }
698 let str = core::str::from_utf8(&str[.. len]).map_err(|_| JsonError::InternalError)?;
699 <i64 as core::str::FromStr>::from_str(str).map_err(|_| JsonError::TypeError)
700 }
701
702 pub fn as_f64(&self) -> Result<f64, JsonError<'bytes, B, S>> {
707 let bytes = &self.deserializer.as_ref().ok_or(JsonError::InternalError)?.bytes;
708
709 const MAX_DOUBLE_LEN: usize =
724 1 + ((f64::MAX_10_EXP as usize) + 1) + 1 + (f64::DIGITS as usize) + 1 + 1 + 4;
725 let len = number::is_number_str(bytes)?;
726
727 let mut src = 0;
728 let mut dst = 0;
729 let mut str = [0; MAX_DOUBLE_LEN];
730 let mut found_non_zero_digit = false;
731 let mut found_decimal = false;
732 let mut insignificant_digits = None;
733 #[allow(clippy::explicit_counter_loop)]
734 for i in 0 .. len {
735 let byte = bytes.peek(src).map_err(JsonError::BytesError)?;
736 src += 1;
737
738 if matches!(byte, b'1' ..= b'9') {
743 found_non_zero_digit = true;
744 if found_decimal {
745 insignificant_digits = i.checked_add(f64::DIGITS as usize - 1);
746 }
747 }
748
749 if byte == b'.' {
751 found_decimal = true;
752 if found_non_zero_digit {
753 insignificant_digits = i.checked_add(f64::DIGITS as usize);
754 }
755 }
756
757 if let Some(insignificant_digits) = insignificant_digits {
764 if (i > insignificant_digits) && byte.is_ascii_digit() {
765 continue;
766 }
767 }
768
769 if matches!(byte, b'e' | b'E') {
771 insignificant_digits = None;
772 }
773
774 if dst == str.len() {
775 Err(JsonError::TypeError)?;
776 }
777 str[dst] = byte;
779 dst += 1;
780 }
781 let str = core::str::from_utf8(&str[.. len]).map_err(|_| JsonError::InternalError)?;
782 <f64 as core::str::FromStr>::from_str(str).map_err(|_| JsonError::TypeError)
783 }
784
785 #[inline(always)]
787 pub fn as_bool(&self) -> Result<bool, JsonError<'bytes, B, S>> {
788 as_bool(&self.deserializer.as_ref().ok_or(JsonError::InternalError)?.bytes)
789 }
790
791 #[inline(always)]
793 pub fn is_null(&self) -> Result<bool, JsonError<'bytes, B, S>> {
794 is_null(&self.deserializer.as_ref().ok_or(JsonError::InternalError)?.bytes)
795 }
796}