1#![doc = include_str!("../README.md")]
18#![cfg_attr(not(feature = "std"), no_std)]
19
20mod error;
21pub use error::JSONParsingError;
22
23#[cfg(any(feature = "small_number_parsing", test))]
24mod number_parsing;
25
26static PARSE_INT: fn(&str) -> Result<isize, core::num::ParseIntError> =
29 <isize as core::str::FromStr>::from_str;
30
31#[cfg(not(feature = "small_number_parsing"))]
32static PARSE_FLOAT: fn(&str) -> Result<f32, core::num::ParseFloatError> =
33 <f32 as core::str::FromStr>::from_str;
34#[cfg(feature = "small_number_parsing")]
35static PARSE_FLOAT: fn(&str) -> Result<f32, ()> = number_parsing::parse_float;
36
37#[derive(Copy, Clone, PartialEq, Eq, Debug)]
49pub enum JSONValueType {
50 String,
51 Number,
52 Object,
53 Array,
54 Bool,
55 Null,
56 Error,
57}
58
59#[derive(Copy, Clone, Debug)]
60pub struct JSONValue<'a> {
61 contents: &'a str,
62 pub value_type: JSONValueType,
63}
64
65fn trim_start(value: &str) -> (&str, usize) {
66 let value_len = value.len();
67 let value = value.trim_start();
70 (value, value_len - value.len())
71}
72
73impl<'a> JSONValue<'a> {
74 pub fn load(contents: &'a str) -> JSONValue {
83 let (contents, _) = trim_start(contents);
84 let value_type = JSONValue::peek_value_type(contents);
85 JSONValue {
86 contents,
87 value_type,
88 }
89 }
90
91 fn peek_value_type(contents: &'a str) -> JSONValueType {
96 match contents.chars().next() {
98 Some('{') => JSONValueType::Object,
99 Some('[') => JSONValueType::Array,
100 Some('"') => JSONValueType::String,
101 Some('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '-') => {
102 JSONValueType::Number
103 }
104 Some('t' | 'f') => JSONValueType::Bool,
105 Some('n') => JSONValueType::Null,
106 _ => JSONValueType::Error,
107 }
108 }
109
110 pub fn verify(&self) -> Result<(), JSONParsingError> {
125 JSONValue::parse_with_len(self.contents)?;
126 Ok(())
127 }
128
129 pub fn load_and_verify(contents: &'a str) -> Result<JSONValue, JSONParsingError> {
133 let value = JSONValue::load(contents);
134 value.verify()?;
135 Ok(value)
136 }
137
138 fn parse_with_len(contents: &'a str) -> Result<(JSONValue, usize), JSONParsingError> {
141 let (contents, whitespace_trimmed) = trim_start(contents);
142 let (value_type, value_len) = match contents.chars().next() {
143 Some('{') => {
144 let mut value_len = 1;
145 let mut contents = &contents[value_len..];
146 while !contents.is_empty() {
147 if contents.trim_start().starts_with('}') {
148 value_len += trim_start(contents).1 + 1;
149 break;
150 }
151 let (item, item_len) = JSONValue::parse_with_len(contents)?;
152 if item.value_type != JSONValueType::String {
153 return Err(JSONParsingError::CannotParseString);
154 }
155 let (new_contents, whitespace) = trim_start(&contents[item_len..]);
156 contents = new_contents;
157 value_len += item_len + whitespace;
158 if contents.is_empty() {
159 return Err(JSONParsingError::EndOfStream);
160 } else if contents.starts_with(':') {
161 value_len += 1;
162 contents = &contents[1..];
163 } else {
164 return Err(JSONParsingError::UnexpectedToken);
165 }
166
167 let (_, item_len) = JSONValue::parse_with_len(contents)?;
168 let (new_contents, whitespace) = trim_start(&contents[item_len..]);
169 contents = new_contents;
170 value_len += item_len + whitespace;
171 if contents.is_empty() {
172 return Err(JSONParsingError::EndOfStream);
173 } else if contents.starts_with(',') {
174 value_len += 1;
175 contents = &contents[1..];
176 } else if !contents.starts_with('}') {
177 return Err(JSONParsingError::UnexpectedToken);
178 }
179 }
180 (JSONValueType::Object, value_len)
181 }
182 Some('[') => {
183 let mut value_len = 1;
184 let mut contents = &contents[value_len..];
185 while !contents.is_empty() {
186 if contents.trim_start().starts_with(']') {
187 value_len += trim_start(contents).1 + 1;
188 break;
189 }
190 let (_, item_len) = JSONValue::parse_with_len(contents)?;
191 let (new_contents, whitespace) = trim_start(&contents[item_len..]);
192 contents = new_contents;
193 value_len += item_len + whitespace;
194 if contents.is_empty() {
195 return Err(JSONParsingError::EndOfStream);
196 } else if contents.starts_with(',') {
197 value_len += 1;
198 contents = &contents[1..];
199 } else if !contents.starts_with(']') {
200 return Err(JSONParsingError::UnexpectedToken);
201 }
202 }
203 (JSONValueType::Array, value_len)
204 }
205 Some('"') => {
206 let mut value_len = 1;
207 let mut is_escaped = false;
208 for chr in contents[1..].chars() {
209 value_len += chr.len_utf8();
210 if chr == '"' && !is_escaped {
211 break;
212 } else if chr == '\\' {
213 is_escaped = !is_escaped;
214 } else {
215 is_escaped = false;
216 }
217 }
218 (JSONValueType::String, value_len)
219 }
220 Some('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '-') => {
221 let mut value_len = 0;
222 for chr in contents.chars() {
223 match chr {
224 '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '-' | 'e'
225 | 'E' | '.' => {
226 value_len += chr.len_utf8();
227 }
228 _ => {
229 break;
230 }
231 }
232 }
233 (JSONValueType::Number, value_len)
234 }
235 Some('t') => {
236 if &contents[..4] != "true" {
237 return Err(JSONParsingError::UnexpectedToken);
238 }
239 (JSONValueType::Bool, 4)
240 }
241 Some('f') => {
242 if &contents[..5] != "false" {
243 return Err(JSONParsingError::UnexpectedToken);
244 }
245 (JSONValueType::Bool, 5)
246 }
247 Some('n') => {
248 if &contents[..4] != "null" {
249 return Err(JSONParsingError::UnexpectedToken);
250 }
251 (JSONValueType::Null, 4)
252 }
253 _ => {
254 return Err(JSONParsingError::UnexpectedToken);
255 }
256 };
257 Ok((
258 JSONValue {
259 contents: &contents[..value_len],
260 value_type,
261 },
262 whitespace_trimmed + value_len,
263 ))
264 }
265
266 pub fn is_null(&self) -> bool {
280 self.contents.trim_end() == "null"
281 }
282
283 pub fn read_boolean(&self) -> Result<bool, JSONParsingError> {
297 if self.value_type != JSONValueType::Bool {
298 return Err(JSONParsingError::CannotParseBoolean);
299 }
300 let contents = self.contents.trim_end();
301 if contents == "true" {
302 Ok(true)
303 } else if contents == "false" {
304 Ok(false)
305 } else {
306 Err(JSONParsingError::CannotParseBoolean)
307 }
308 }
309
310 pub fn read_integer(&self) -> Result<isize, JSONParsingError> {
324 if self.value_type != JSONValueType::Number {
325 return Err(JSONParsingError::CannotParseInteger);
326 }
327 let contents = self.contents.trim_end();
328 PARSE_INT(contents).map_err(|_| JSONParsingError::CannotParseInteger)
329 }
330
331 pub fn read_float(&self) -> Result<f32, JSONParsingError> {
345 if self.value_type != JSONValueType::Number {
346 return Err(JSONParsingError::CannotParseFloat);
347 }
348 let contents = self.contents.trim_end();
349 PARSE_FLOAT(contents).map_err(|_| JSONParsingError::CannotParseFloat)
350 }
351
352 pub fn read_string(&self) -> Result<&'a str, JSONParsingError> {
364 let (_, length) = JSONValue::parse_with_len(self.contents)?;
365 if self.value_type != JSONValueType::String {
366 return Err(JSONParsingError::CannotParseString);
367 }
368 Ok(&self.contents[1..length - 1])
369 }
370
371 pub fn iter_array(&self) -> Result<JSONArrayIterator<'a>, JSONParsingError> {
375 if self.value_type != JSONValueType::Array {
376 return Err(JSONParsingError::CannotParseArray);
377 }
378 Ok(JSONArrayIterator {
379 contents: &self.contents[1..],
380 })
381 }
382
383 pub fn iter_string(&self) -> Result<EscapedStringIterator<'a>, JSONParsingError> {
398 if self.value_type != JSONValueType::String {
399 return Err(JSONParsingError::CannotParseString);
400 }
401 Ok(EscapedStringIterator {
402 contents: self.contents[1..].chars(),
403 done: false,
404 })
405 }
406
407 pub fn iter_object(&self) -> Result<JSONObjectIterator<'a>, JSONParsingError> {
411 if self.value_type != JSONValueType::Object {
412 return Err(JSONParsingError::CannotParseObject);
413 }
414 Ok(JSONObjectIterator {
415 contents: &self.contents[1..],
416 })
417 }
418
419 pub fn get_key_value(&self, key: &str) -> Result<JSONValue, JSONParsingError> {
427 self.iter_object()?
428 .find(|item| matches!(item, Ok((k, _)) if k == &key))
429 .map(|item| item.unwrap().1)
430 .ok_or(JSONParsingError::KeyNotFound)
431 }
432}
433
434pub struct JSONObjectIterator<'a> {
440 contents: &'a str,
441}
442
443impl<'a> Iterator for JSONObjectIterator<'a> {
444 type Item = Result<(&'a str, JSONValue<'a>), JSONParsingError>;
445
446 fn next(&mut self) -> Option<Self::Item> {
447 self.contents = self.contents.trim_start();
448 if self.contents.is_empty() {
449 None
450 } else {
451 if !self.contents.starts_with('\"') {
452 self.contents = &self.contents[..0];
453 return None;
454 }
455 match JSONValue::parse_with_len(self.contents) {
457 Ok((_, key_len)) => {
458 let this_key = &self.contents[1..key_len - 1];
459 self.contents = &self.contents[key_len..].trim_start()[1..];
460
461 match JSONValue::parse_with_len(self.contents) {
462 Ok((this_value, value_len)) => {
463 self.contents = &self.contents[value_len..].trim_start();
464 if !self.contents.is_empty() {
465 self.contents = &self.contents[1..];
466 }
467 Some(Ok((this_key, this_value)))
468 }
469 Err(e) => {
470 self.contents = &self.contents[..0];
471 Some(Err(e))
472 }
473 }
474 }
475 Err(e) => {
476 self.contents = &self.contents[..0];
477 Some(Err(e))
478 }
479 }
480 }
481 }
482}
483
484pub struct JSONArrayIterator<'a> {
488 contents: &'a str,
489}
490
491impl<'a> Iterator for JSONArrayIterator<'a> {
492 type Item = JSONValue<'a>;
493
494 fn next(&mut self) -> Option<Self::Item> {
495 match JSONValue::parse_with_len(self.contents) {
496 Ok((value, value_len)) => {
497 self.contents = &self.contents[value_len..].trim_start()[1..];
498 Some(value)
499 }
500 _ => None,
501 }
502 }
503}
504
505pub struct EscapedStringIterator<'a> {
509 contents: core::str::Chars<'a>,
510 done: bool,
511}
512
513impl<'a> Iterator for EscapedStringIterator<'a> {
514 type Item = Result<char, JSONParsingError>;
515
516 fn next(&mut self) -> Option<Self::Item> {
517 if self.done {
518 None
519 } else {
520 let chr = self.contents.next();
521 match chr {
522 Some('\\') => {
523 let chr = self.contents.next();
524 match chr {
525 Some('"' | '\\' | '/') => chr.map(Ok),
526 Some('b') => Some(Ok('\x08')),
527 Some('f') => Some(Ok('\x0c')),
528 Some('n') => Some(Ok('\n')),
529 Some('t') => Some(Ok('\t')),
530 Some('r') => Some(Ok('\r')),
531 Some('u') => {
532 let mut get_digit = || {
533 self.contents
534 .next()
535 .and_then(|x| x.to_digit(16))
536 .ok_or(JSONParsingError::TooShortEscapeSequence)
537 };
538 let mut parse_unicode = || {
539 let code = [get_digit()?, get_digit()?, get_digit()?, get_digit()?];
540 let code =
541 (code[0] << 12) | (code[1] << 8) | (code[2] << 4) | code[3];
542 char::from_u32(code)
543 .ok_or(JSONParsingError::InvalidUnicodeEscapeSequence)
544 };
545 match parse_unicode() {
546 Ok(chr) => Some(Ok(chr)),
547 Err(e) => {
548 self.done = true;
549 Some(Err(e))
550 }
551 }
552 }
553 Some(x) => {
554 self.done = true;
555 Some(Err(JSONParsingError::InvalidEscapeSequence(x)))
556 }
557 None => None,
558 }
559 }
560 Some('"') => {
561 self.done = true;
562 None
563 }
564 None => {
565 self.done = true;
566 Some(Err(JSONParsingError::EndOfStream))
567 }
568 _ => chr.map(Ok),
569 }
570 }
571 }
572}
573
574#[cfg(test)]
575mod test {
576 use super::*;
577 extern crate std;
578
579 #[test]
580 fn is_null() {
581 assert_eq!(JSONValue::load("null").is_null(), true);
582 assert_eq!(JSONValue::load("1234").is_null(), false);
583 assert_eq!(JSONValue::load("<!or").is_null(), false);
584 }
585
586 #[test]
587 fn boolean() {
588 assert_eq!(JSONValue::load("true").read_boolean(), Ok(true));
589 assert_eq!(JSONValue::load("false").read_boolean(), Ok(false));
590 assert_eq!(
591 JSONValue::load("foo").read_boolean(),
592 Err(JSONParsingError::CannotParseBoolean)
593 );
594 }
595
596 #[test]
597 fn integer() {
598 let (value, value_len) = JSONValue::parse_with_len("42").unwrap();
599 assert_eq!(value.value_type, JSONValueType::Number);
600 assert_eq!(value_len, 2);
601 assert_eq!(value.read_integer(), Ok(42));
602 assert!(value.read_string().is_err());
603
604 assert_eq!(JSONValue::load("-98").read_integer(), Ok(-98));
605 assert_eq!(JSONValue::load("-99 ").read_integer(), Ok(-99));
606 }
607
608 #[test]
609 fn float() {
610 let (value, value_len) = JSONValue::parse_with_len("3.141592").unwrap();
611 assert_eq!(value.value_type, JSONValueType::Number);
612 assert_eq!(value_len, "3.141592".len());
613 assert_eq!(
614 value.read_integer(),
615 Err(JSONParsingError::CannotParseInteger)
616 );
617 assert_eq!(
618 value.read_string(),
619 Err(JSONParsingError::CannotParseString)
620 );
621 assert!((value.read_float().unwrap() - 3.141592).abs() < 0.0001);
622
623 assert_eq!(
624 JSONValue::load("-3.43w").read_float(),
625 Err(JSONParsingError::CannotParseFloat)
626 );
627 }
628
629 #[test]
630 fn string() {
631 let (value, value_len) = JSONValue::parse_with_len("\"hello world\"").unwrap();
632 assert_eq!(value.value_type, JSONValueType::String);
633 assert_eq!(value_len, "\"hello world\"".len());
634 assert!(value.read_integer().is_err());
635 assert_eq!(value.read_string(), Ok("hello world"));
636
637 let value = JSONValue::load("\"hello world\" ");
638 assert_eq!(value.read_string(), Ok("hello world"));
639 }
640
641 #[test]
642 fn array() {
643 let (value, value_len) = JSONValue::parse_with_len("[1,2,3]").unwrap();
644 assert_eq!(value.value_type, JSONValueType::Array);
645 assert_eq!(value_len, "[1,2,3]".len());
646 let (value, value_len) = JSONValue::parse_with_len("[]").unwrap();
647 assert_eq!(value.value_type, JSONValueType::Array);
648 assert_eq!(value_len, "[]".len());
649 let (value, value_len) = JSONValue::parse_with_len(" [\n ]").unwrap();
650 assert_eq!(value.value_type, JSONValueType::Array);
651 assert_eq!(value_len, " [\n ]".len());
652 let (value, value_len) = JSONValue::parse_with_len("[1 , 2\t,\r3\n]").unwrap();
653 assert_eq!(value.value_type, JSONValueType::Array);
654 assert_eq!(value_len, "[1 , 2\t,\r3\n]".len());
655
656 assert!(value.read_integer().is_err());
657 assert!(value.read_string().is_err());
658 assert_eq!(
659 value.iter_array().unwrap().nth(0).unwrap().read_integer(),
660 Ok(1)
661 );
662 assert_eq!(
663 value.iter_array().unwrap().nth(1).unwrap().read_integer(),
664 Ok(2)
665 );
666 assert_eq!(
667 value.iter_array().unwrap().nth(2).unwrap().read_integer(),
668 Ok(3)
669 );
670 }
671
672 #[test]
673 fn object() {
674 let input = "{
675 \"id\": 0,
676 \"name\": \"Ginger Fuller\"}";
677 let (value, value_len) = JSONValue::parse_with_len(input).unwrap();
678 assert_eq!(value.value_type, JSONValueType::Object);
679 assert_eq!(value_len, input.len());
680
681 assert!(value.read_integer().is_err());
682 assert!(value.read_string().is_err());
683 assert_eq!(value.get_key_value("id").unwrap().read_integer(), Ok(0));
684 assert_eq!(
685 value.get_key_value("name").unwrap().read_string(),
686 Ok("Ginger Fuller")
687 );
688 assert_eq!(
689 value.get_key_value("surname").err(),
690 Some(JSONParsingError::KeyNotFound)
691 );
692
693 assert!(JSONValue::load("{\"foo\":[{}]}").value_type != JSONValueType::Error);
694 assert!(JSONValue::load("[{\"foo\":{}}]").value_type != JSONValueType::Error);
695 }
696 #[test]
697
698 fn this_broke_once() {
699 assert!(
700 JSONValue::load(
701 r##"
702[{"a":{"email":"d@"},"m":"#20\n\n.\n"}]
703 "##
704 )
705 .value_type
706 != JSONValueType::Error
707 )
708 }
709
710 #[test]
711 fn integer_whitespace() {
712 let (value, value_len) = JSONValue::parse_with_len(" 42 ").unwrap();
713 assert_eq!(value.value_type, JSONValueType::Number);
714 assert_eq!(value_len, " 42".len());
715 let (value, value_len) = JSONValue::parse_with_len("\n 42\r").unwrap();
716 assert_eq!(value.value_type, JSONValueType::Number);
717 assert_eq!(value_len, "\n 42".len());
718 }
719
720 #[test]
721 fn string_whitespace() {
722 let (value, value_len) = JSONValue::parse_with_len(" \"foo me a bar\" ").unwrap();
723 assert_eq!(value.value_type, JSONValueType::String);
724 assert_eq!(value_len, " \"foo me a bar\"".len());
725 let (value, value_len) = JSONValue::parse_with_len("\n \"a bar\n I said.\"\r").unwrap();
726 assert_eq!(value.value_type, JSONValueType::String);
727 assert_eq!(value_len, "\n \"a bar\n I said.\"".len());
728 }
729
730 #[test]
731 fn peeking_value_type() {
732 assert_eq!(JSONValue::peek_value_type("123"), JSONValueType::Number);
733 assert_eq!(JSONValue::peek_value_type("12.3"), JSONValueType::Number);
734 assert_eq!(JSONValue::peek_value_type("12.3e10"), JSONValueType::Number);
735 assert_eq!(JSONValue::peek_value_type("-3"), JSONValueType::Number);
736 assert_eq!(JSONValue::peek_value_type("-3.5"), JSONValueType::Number);
737 assert_eq!(JSONValue::peek_value_type("null"), JSONValueType::Null);
738 assert_eq!(JSONValue::peek_value_type("true"), JSONValueType::Bool);
739 assert_eq!(JSONValue::peek_value_type("false"), JSONValueType::Bool);
740 assert_eq!(JSONValue::peek_value_type("[]"), JSONValueType::Array);
741 assert_eq!(JSONValue::peek_value_type("[12]"), JSONValueType::Array);
742 assert_eq!(JSONValue::peek_value_type("[1,2]"), JSONValueType::Array);
743 assert_eq!(JSONValue::peek_value_type("[[]]"), JSONValueType::Array);
744 assert_eq!(JSONValue::peek_value_type("\"foo\""), JSONValueType::String);
745 assert_eq!(JSONValue::peek_value_type("{}"), JSONValueType::Object);
746 assert_eq!(
747 JSONValue::peek_value_type("{\"a\":2}"),
748 JSONValueType::Object
749 );
750 assert_eq!(JSONValue::peek_value_type("<"), JSONValueType::Error);
751 assert_eq!(JSONValue::peek_value_type("bar"), JSONValueType::Error);
752 }
753
754 #[test]
755 fn verifying() {
756 assert!(JSONValue::load_and_verify(" 123 ").is_ok());
757 assert!(JSONValue::load_and_verify("[123]").is_ok());
758 assert!(JSONValue::load_and_verify("\"foo\"").is_ok());
759 }
760
761 #[test]
762 fn string_iterator() {
763 let try_parse_string = |s| {
764 JSONValue::load(s)
765 .iter_string()
766 .unwrap()
767 .collect::<Result<std::string::String, _>>()
768 };
769 let value = try_parse_string("\"I have a dream\"").unwrap();
770 assert_eq!(value, "I have a dream");
771
772 let value = try_parse_string("\"\\\"I have a dream\\\"\"").unwrap();
773 assert_eq!(value, "\"I have a dream\"");
774
775 let value = try_parse_string(r#" "\"I\n\thave\b\fa\\dream\/\"\u00a3" "#).unwrap();
776 assert_eq!(value, "\"I\n\thave\x08\x0ca\\dream/\"£");
777
778 let value = try_parse_string(r#" " "#);
779 assert!(matches!(value, Err(JSONParsingError::EndOfStream)));
780 let value = try_parse_string(r#" "foo\" "#);
781 assert!(matches!(value, Err(JSONParsingError::EndOfStream)));
782 let value = try_parse_string(r#" "Odd escape: \?" "#);
783 assert!(matches!(
784 value,
785 Err(JSONParsingError::InvalidEscapeSequence('?'))
786 ));
787 let value = try_parse_string(r#" "\uwxyz" "#);
788 assert!(matches!(
789 value,
790 Err(JSONParsingError::TooShortEscapeSequence)
791 ));
792 let value = try_parse_string(r#" "\u012" "#);
793 assert!(matches!(
794 value,
795 Err(JSONParsingError::TooShortEscapeSequence)
796 ));
797 let value = try_parse_string(r#" "\ud834" "#);
799 assert!(matches!(
800 value,
801 Err(JSONParsingError::InvalidUnicodeEscapeSequence)
802 ));
803 }
804
805 #[test]
806 fn object_iterator() {
807 let json_value = JSONValue::load("{\"foo\" : [], \"bar\":{\"baz\": 2}}");
808 let keys = ["foo", "bar"];
809 for (item, expected_key) in json_value.iter_object().unwrap().zip(&keys) {
810 assert_eq!(item.unwrap().0, *expected_key);
811 }
812 }
813
814 #[test]
815 fn string_borrow_past_lifetime_of_value() {
816 let s = "\"abc\"";
817 let t: &str;
818 {
819 t = JSONValue::load(s).read_string().unwrap();
820 }
821 assert_eq!(t, &s[1..s.len() - 1]);
822 }
823
824 #[test]
825 fn empty_object() {
826 let json_value = JSONValue::load("{}");
827 assert_eq!(json_value.value_type, JSONValueType::Object);
828 assert_eq!(
829 json_value.get_key_value("foo").err(),
830 Some(JSONParsingError::KeyNotFound)
831 );
832 assert_eq!(json_value.iter_object().unwrap().count(), 0);
833 }
834}