1use std::error::Error;
68use std::fmt;
69use std::iter::Peekable;
70
71use indexmap::IndexMap;
72
73#[derive(Debug)]
74pub enum JsonValue {
75 Object(IndexMap<String, JsonValue>),
76 Array(Vec<JsonValue>),
77 String(String),
78 Number(f64),
79 Bool(bool),
80 Null,
81}
82
83impl JsonValue {
84 pub fn from<S: AsRef<str>>(s: S) -> Result<JsonValue, ParseError> {
85 parse(s)
86 }
87
88 pub fn new_object() -> JsonValue {
89 JsonValue::Object(IndexMap::default())
90 }
91 pub fn new_array() -> JsonValue {
92 JsonValue::Array(Vec::default())
93 }
94 pub fn new_string() -> JsonValue {
95 JsonValue::String(String::default())
96 }
97 pub fn new_number() -> JsonValue {
98 JsonValue::Number(f64::default())
99 }
100 pub fn new_bool() -> JsonValue {
101 JsonValue::Bool(bool::default())
102 }
103 pub fn new_null() -> JsonValue {
104 JsonValue::Null
105 }
106
107 pub fn is_object(&self) -> bool {
108 matches!(self, JsonValue::Object(_))
109 }
110 pub fn is_array(&self) -> bool {
111 matches!(self, JsonValue::Array(_))
112 }
113 pub fn is_string(&self) -> bool {
114 matches!(self, JsonValue::String(_))
115 }
116 pub fn is_number(&self) -> bool {
117 matches!(self, JsonValue::Number(_))
118 }
119 pub fn is_bool(&self) -> bool {
120 matches!(self, JsonValue::Bool(_))
121 }
122 pub fn is_null(&self) -> bool {
123 matches!(self, JsonValue::Null)
124 }
125
126 pub fn as_object(&self) -> Option<&IndexMap<String, JsonValue>> {
127 match self { JsonValue::Object(o) => Some(o), _ => None }
128 }
129 pub fn as_array(&self) -> Option<&Vec<JsonValue>> {
130 match self { JsonValue::Array(a) => Some(a), _ => None }
131 }
132 pub fn as_string(&self) -> Option<&String> {
133 match self { JsonValue::String(s) => Some(s), _ => None }
134 }
135 pub fn as_number(&self) -> Option<&f64> {
136 match self { JsonValue::Number(n) => Some(n), _ => None }
137 }
138 pub fn as_bool(&self) -> Option<&bool> {
139 match self { JsonValue::Bool(b) => Some(b), _ => None }
140 }
141 pub fn as_null(&self) -> Option<&()> {
142 match self { JsonValue::Null => Some(&()), _ => None }
143 }
144
145 pub fn into_object(self) -> Option<IndexMap<String, JsonValue>> {
146 match self { JsonValue::Object(o) => Some(o), _ => None }
147 }
148 pub fn into_array(self) -> Option<Vec<JsonValue>> {
149 match self { JsonValue::Array(a) => Some(a), _ => None }
150 }
151 pub fn into_string(self) -> Option<String> {
152 match self { JsonValue::String(s) => Some(s), _ => None }
153 }
154 pub fn into_number(self) -> Option<f64> {
155 match self { JsonValue::Number(n) => Some(n), _ => None }
156 }
157 pub fn into_bool(self) -> Option<bool> {
158 match self { JsonValue::Bool(b) => Some(b), _ => None }
159 }
160 pub fn into_null(self) -> Option<()> {
161 match self { JsonValue::Null => Some(()), _ => None }
162 }
163}
164
165impl AsRef<JsonValue> for JsonValue {
166 fn as_ref(&self) -> &JsonValue {
167 self
168 }
169}
170
171impl PartialEq for JsonValue {
172 fn eq(&self, other: &Self) -> bool {
173 match (self, other) {
174 (JsonValue::Object(a), JsonValue::Object(b)) => a == b,
175 (JsonValue::Array(a), JsonValue::Array(b)) => a == b,
176 (JsonValue::String(a), JsonValue::String(b)) => a == b,
177 (JsonValue::Number(a), JsonValue::Number(b)) => a == b || a.is_nan() && b.is_nan(),
178 (JsonValue::Bool(a), JsonValue::Bool(b)) => a == b,
179 (JsonValue::Null, JsonValue::Null) => true,
180 _ => false,
181 }
182 }
183}
184
185impl Eq for JsonValue {}
186
187impl fmt::Display for JsonValue {
188 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
189 write!(f, "{}", stringify(self))
190 }
191}
192
193impl std::str::FromStr for JsonValue {
194 type Err = ParseError;
195
196 fn from_str(s: &str) -> Result<Self, Self::Err> {
197 parse(s)
198 }
199}
200
201pub fn stringify<O: AsRef<JsonValue>>(o: O) -> String {
202 let o = o.as_ref();
203 let result = match o {
204 JsonValue::Null => "null".to_string(),
205 JsonValue::Bool(b) => b.to_string(),
206 JsonValue::Number(n) => {
207 if *n == 0.0 {
208 "0".to_string()
209 } else if !n.is_finite() {
210 "null".to_string()
211 } else {
212 let abs = n.abs();
213 if abs < 1e-6 || abs >= 1e21 {
214 let s = format!("{:e}", n);
215 let (mantissa, exponent) = s.split_at(s.find('e').unwrap() + 1);
216 if exponent.starts_with('-') {
217 s
218 } else {
219 format!("{}+{}", mantissa, exponent)
220 }
221 } else {
222 n.to_string()
223 }
224 }
225 },
226 JsonValue::String(s) => {
227 let mut escaped = String::with_capacity(s.len() + 2);
228 escaped.push('"');
229 for c in s.chars() {
230 match c {
231 '"' => escaped.push_str("\\\""),
232 '\\' => escaped.push_str("\\\\"),
233 '\n' => escaped.push_str("\\n"),
234 '\t' => escaped.push_str("\\t"),
235 '\r' => escaped.push_str("\\r"),
236 '\x08' => escaped.push_str("\\b"),
237 '\x0C' => escaped.push_str("\\f"),
238 c if (c as u32) < 0x20 => {
239 use std::fmt::Write;
240 write!(escaped, "\\u{:04x}", c as u32).unwrap();
241 }
242 _ => escaped.push(c),
243 }
244 }
245 escaped.push('"');
246 escaped
247 },
248 JsonValue::Array(a) => {
249 let mut elements = Vec::new();
250 for item in a {
251 elements.push(stringify(item));
252 }
253 format!("[{}]", elements.join(","))
254 },
255 JsonValue::Object(d) => {
256 let mut members = Vec::new();
257 for (k, v) in d {
258 members.push(format!("\"{}\":{}", k, stringify(v)));
259 }
260 format!("{{{}}}", members.join(","))
261 },
262 };
263 result
264}
265
266#[derive(Debug, PartialEq, Eq)]
267pub enum ParseError {
268 UnexpectedEndOfJsonInput,
269 UnexpectedToken { ch: char, pos: usize },
270 UnterminatedString { pos: usize },
271 BadControlCharacter { pos: usize },
272 BadEscapedCharacter { pos: usize },
273 BadUnicodeEscape { pos: usize },
274 IllegalUnicodeEscapeOrSurrogate { pos: usize },
275 NoNumberAfterMinusSign { pos: usize },
276 UnexpectedNumber { pos: usize },
277 UnterminatedFractionalNumber { pos: usize },
278 ExponentPartIsMissingANumber { pos: usize },
279 UnexpectedNonWhitespaceAfterJson { ch: char, pos: usize },
280 UnexpectedCharacterAfterArrayElement { ch: char, pos: usize },
281 UnexpectedEndOfArray,
282 ExpectedPropertyName { pos: usize },
283 ExpectedSemicolonAfterPropertyName { pos: usize },
284 UnexpectedCharacterAfterObjectMember { ch: char, pos: usize },
285 UnexpectedEndOfObject,
286}
287
288impl Error for ParseError {}
289
290impl fmt::Display for ParseError {
291 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
292 match self {
293 ParseError::UnexpectedEndOfJsonInput => {
294 write!(f, "Unexpected end of JSON input")
295 }
296 ParseError::UnexpectedToken { ch, pos } => {
297 write!(f, "Unexpected token '{}' at position {}", ch, pos)
298 }
299 ParseError::UnterminatedString { pos } => {
300 write!(f, "Unterminated string in JSON at position {}", pos)
301 }
302 ParseError::BadControlCharacter { pos } => {
303 write!(f, "Bad control character in string literal in JSON at position {}", pos)
304 }
305 ParseError::BadEscapedCharacter { pos } => {
306 write!(f, "Bad escaped character in JSON at position {}", pos)
307 }
308 ParseError::BadUnicodeEscape { pos } => {
309 write!(f, "Bad Unicode escape in JSON at position {}", pos)
310 }
311 ParseError::IllegalUnicodeEscapeOrSurrogate { pos } => {
312 write!(f, "Illegal or Surrogate Unicode escape sequence at position {}", pos)
313 }
314 ParseError::NoNumberAfterMinusSign { pos } => {
315 write!(f, "No number after minus sign in JSON at position {}", pos)
316 }
317 ParseError::UnexpectedNumber { pos } => {
318 write!(f, "Unexpected number in JSON at position {}", pos)
319 }
320 ParseError::UnterminatedFractionalNumber { pos } => {
321 write!(f, "Unterminated fractional number in JSON at position {}", pos)
322 }
323 ParseError::ExponentPartIsMissingANumber { pos } => {
324 write!(f, "Exponent part is missing a number in JSON at position {}", pos)
325 }
326 ParseError::UnexpectedNonWhitespaceAfterJson { ch, pos } => {
327 write!(f, "Unexpected non-whitespace character '{}' after JSON at position {}", ch, pos)
328 }
329 ParseError::UnexpectedCharacterAfterArrayElement { ch, pos } => {
330 write!(f, "Unexpected character '{}' after array element in JSON at position {}: expected ',' or ']'", ch, pos)
331 }
332 ParseError::UnexpectedEndOfArray => {
333 write!(f, "Unexpected end of an array: expected ']'")
334 }
335 ParseError::ExpectedPropertyName { pos } => {
336 write!(f, "Expected property name or '}}' at position {}", pos)
337 }
338 ParseError::ExpectedSemicolonAfterPropertyName { pos } => {
339 write!(f, "Expected ':' after property name in JSON at position {}", pos)
340 }
341 ParseError::UnexpectedCharacterAfterObjectMember { ch, pos } => {
342 write!(f, "Unexpected character '{}' after object member in JSON at position {}: expected ',' or '}}'", ch, pos)
343 }
344 ParseError::UnexpectedEndOfObject => {
345 write!(f, "Unexpected end of an object: expected '}}'")
346 }
347 }
348 }
349}
350
351pub fn parse<S: AsRef<str>>(s: S) -> Result<JsonValue, ParseError> {
352 let mut s = s.as_ref().chars().enumerate().peekable();
353 let result = match_value(&mut s)?;
354 skip_whitespace(&mut s);
355 if let Some(&(p, c)) = s.peek() {
356 return Err(ParseError::UnexpectedNonWhitespaceAfterJson { ch: c, pos: p })
357 }
358 Ok(result)
359}
360
361fn skip_whitespace<I: Iterator<Item = (usize, char)>>(chars: &mut Peekable<I>) {
362 while matches!(chars.peek(), Some((_, ' ' | '\t' | '\n' | '\r'))) {
363 chars.next();
364 }
365}
366
367fn match_value<I: Iterator<Item = (usize, char)>>(chars: &mut Peekable<I>) -> Result<JsonValue, ParseError> {
368 skip_whitespace(chars);
369 if let Some(&(_, c)) = chars.peek() {
370 if c == '{' {
371 match_object(chars)
372 } else if c == '[' {
373 match_array(chars)
374 } else if c == '"' {
375 match_string(chars)
376 } else if c == '-' || c >= '0' && c <= '9' {
377 match_number(chars)
378 } else {
379 match_other(chars)
380 }
381 } else {
382 Err(ParseError::UnexpectedEndOfJsonInput)
383 }
384}
385
386fn match_object<I: Iterator<Item = (usize, char)>>(chars: &mut Peekable<I>) -> Result<JsonValue, ParseError> {
387 chars.next();
388 let mut object = IndexMap::new();
389 skip_whitespace(chars);
390 if let Some(&(_, c)) = chars.peek() {
391 if c == '}' {
392 chars.next();
393 return Ok(JsonValue::Object(object))
394 }
395 } else {
396 return Err(ParseError::UnexpectedEndOfObject)
397 }
398 loop {
399 skip_whitespace(chars);
400 match chars.peek() {
401 None => return Err(ParseError::UnexpectedEndOfObject),
402 Some(&(_, '"')) => {},
403 Some(&(p, _)) => return Err(ParseError::ExpectedPropertyName { pos: p }),
404 };
405 let key = match_string(chars)?.into_string().unwrap();
406 skip_whitespace(chars);
407 match chars.peek() {
408 None => return Err(ParseError::UnexpectedEndOfObject),
409 Some(&(_, ':')) => chars.next(),
410 Some(&(p, _)) => return Err(ParseError::ExpectedSemicolonAfterPropertyName { pos: p }),
411 };
412 let value = match_value(chars)?;
413 object.insert(key, value);
414 skip_whitespace(chars);
415 if let Some(&(p, c)) = chars.peek() {
416 if c == ',' {
417 chars.next();
418 continue;
419 }
420 if c == '}' {
421 chars.next();
422 break;
423 }
424 return Err(ParseError::UnexpectedCharacterAfterObjectMember { ch: c, pos: p })
425 } else {
426 return Err(ParseError::UnexpectedEndOfObject)
427 }
428 }
429 Ok(JsonValue::Object(object))
430}
431
432fn match_array<I: Iterator<Item = (usize, char)>>(chars: &mut Peekable<I>) -> Result<JsonValue, ParseError> {
433 chars.next();
434 let mut array = Vec::new();
435 skip_whitespace(chars);
436 if let Some(&(_, c)) = chars.peek() {
437 if c == ']' {
438 chars.next();
439 return Ok(JsonValue::Array(array))
440 }
441 } else {
442 return Err(ParseError::UnexpectedEndOfArray)
443 }
444 loop {
445 array.push(match_value(chars)?);
446 skip_whitespace(chars);
447 if let Some(&(p, c)) = chars.peek() {
448 if c == ',' {
449 chars.next();
450 continue;
451 }
452 if c == ']' {
453 chars.next();
454 break;
455 }
456 return Err(ParseError::UnexpectedCharacterAfterArrayElement { ch: c, pos: p })
457 } else {
458 return Err(ParseError::UnexpectedEndOfArray)
459 }
460 }
461 Ok(JsonValue::Array(array))
462}
463
464fn match_string<I: Iterator<Item = (usize, char)>>(chars: &mut Peekable<I>) -> Result<JsonValue, ParseError> {
465 let (p_start, c_start) = chars.next().unwrap();
466 assert!(c_start == '"');
467 let mut s = String::new();
468 while let Some((p, c)) = chars.next() {
469 if c == '"' {
470 return Ok(JsonValue::String(s))
471 } else if c == '\\' {
472 if let Some((p1, c1)) = chars.next() {
473 match c1 {
474 '"' | '\\' | '/' => s.push(c1),
475 'n' => s.push('\n'),
476 't' => s.push('\t'),
477 'r' => s.push('\r'),
478 'b' => s.push('\x08'),
479 'f' => s.push('\x14'),
480 'u' => {
481 let next4 = [chars.next(), chars.next(), chars.next(), chars.next()];
482 let mut unicode: u32 = 0;
483 for (i, item) in next4.iter().enumerate() {
484 let (pos, ch) = item.ok_or(ParseError::BadUnicodeEscape { pos: p1 + i + 1 })?;
485 unicode = (unicode << 4) + ch.to_digit(16).ok_or(ParseError::BadUnicodeEscape { pos })?;
486 }
487 s.push(char::from_u32(unicode).ok_or_else(|| ParseError::IllegalUnicodeEscapeOrSurrogate { pos: p })?);
488 },
489 _ => return Err(ParseError::BadEscapedCharacter { pos: p1 }),
490 }
491 } else {
492 return Err(ParseError::UnexpectedEndOfJsonInput)
493 }
494 } else if c >= '\0' && c <= '\x1F' {
495 return Err(ParseError::BadControlCharacter { pos: p })
496 } else {
497 s.push(c);
498 }
499 }
500 Err(ParseError::UnterminatedString { pos: p_start + s.len() + 1 })
501}
502
503fn match_number<I: Iterator<Item = (usize, char)>>(chars: &mut Peekable<I>) -> Result<JsonValue, ParseError> {
504 let (p_start, c_start) = chars.next().unwrap();
505 let mut s = String::from(c_start);
506 match chars.peek() {
508 Some(&(_, '0'..='9')) => {
509 if c_start == '0' {
510 return Err(ParseError::UnexpectedNumber { pos: p_start + 1 })
511 }
512 let (_, c_cur) = chars.next().unwrap();
513 if c_start == '-' && c_cur == '0' && matches!(chars.peek(), Some(&(_, '0'..='9'))) {
514 return Err(ParseError::UnexpectedNumber { pos: p_start + 2 })
515 }
516 s.push(c_cur);
517 while matches!(chars.peek(), Some(&(_, c)) if '0' <= c && c <= '9') {
518 s.push(chars.next().unwrap().1);
519 }
520 }
521 None | Some(_) => {
522 if c_start == '-' {
523 return Err(ParseError::NoNumberAfterMinusSign { pos: p_start + 1 })
524 }
525 }
526 }
527 if matches!(chars.peek(), Some(&(_, '.'))) {
529 let (p_frac, c_frac) = chars.next().unwrap();
530 s.push(c_frac);
531 if let Some(&(p, c)) = chars.peek() {
532 if !('0' <= c && c <= '9') {
533 return Err(ParseError::UnterminatedFractionalNumber { pos: p })
534 }
535 } else {
536 return Err(ParseError::UnterminatedFractionalNumber { pos: p_frac + 1 })
537 }
538 while matches!(chars.peek(), Some(&(_, c)) if '0' <= c && c <= '9') {
539 s.push(chars.next().unwrap().1);
540 }
541 }
542 if matches!(chars.peek(), Some(&(_, 'e' | 'E'))) {
544 let (p_exp, c_exp) = chars.next().unwrap();
545 s.push(c_exp);
546 let has_sign = matches!(chars.peek(), Some(&(_, '+' | '-')));
547 if has_sign {
548 s.push(chars.next().unwrap().1);
549 }
550 if let Some(&(p, c)) = chars.peek() {
551 if !('0' <= c && c <= '9') {
552 return Err(ParseError::ExponentPartIsMissingANumber { pos: p })
553 }
554 } else {
555 return Err(ParseError::ExponentPartIsMissingANumber { pos: p_exp + (has_sign as usize) + 1 })
556 }
557 while matches!(chars.peek(), Some(&(_, c)) if '0' <= c && c <= '9') {
558 s.push(chars.next().unwrap().1);
559 }
560 }
561 Ok(JsonValue::Number(s.parse::<f64>().unwrap()))
562}
563
564fn match_other<I: Iterator<Item = (usize, char)>>(chars: &mut Peekable<I>) -> Result<JsonValue, ParseError> {
565 let (p, c) = chars.next().unwrap();
566 if c == 't' {
567 expect_char(chars, 'r')?;
568 expect_char(chars, 'u')?;
569 expect_char(chars, 'e')?;
570 Ok(JsonValue::Bool(true))
571 } else if c == 'f' {
572 expect_char(chars, 'a')?;
573 expect_char(chars, 'l')?;
574 expect_char(chars, 's')?;
575 expect_char(chars, 'e')?;
576 Ok(JsonValue::Bool(false))
577 } else if c == 'n' {
578 expect_char(chars, 'u')?;
579 expect_char(chars, 'l')?;
580 expect_char(chars, 'l')?;
581 Ok(JsonValue::Null)
582 } else {
583 Err(ParseError::UnexpectedToken { ch: c, pos: p })
584 }
585}
586
587fn expect_char<I: Iterator<Item = (usize, char)>>(chars: &mut Peekable<I>, ch: char) -> Result<(), ParseError> {
588 if let Some(&(p, c)) = chars.peek() {
589 if c == ch {
590 chars.next();
591 Ok(())
592 } else {
593 Err(ParseError::UnexpectedToken { ch: c, pos: p })
594 }
595 } else {
596 Err(ParseError::UnexpectedEndOfJsonInput)
597 }
598}
599
600#[cfg(test)]
601mod tests {
602 use indexmap::indexmap;
603 use super::*;
604
605 #[test]
606 fn test_stringify() {
607 fn case<O: AsRef<JsonValue>, S: AsRef<str>>(o: O, s: S) {
608 let o = o.as_ref();
609 let s = s.as_ref();
610 let s1 = stringify(o);
611 let s2 = o.to_string();
612 assert_eq!(s, s1);
613 assert_eq!(s, s2);
614 }
615
616 case(JsonValue::Null, "null");
617
618 case(JsonValue::Bool(true), "true");
619 case(JsonValue::Bool(false), "false");
620
621 case(JsonValue::Number(0.0), "0");
622 case(JsonValue::Number(-0.0), "0");
623 case(JsonValue::Number(0.1), "0.1");
624 case(JsonValue::Number(0.01), "0.01");
625 case(JsonValue::Number(0.001), "0.001");
626 case(JsonValue::Number(0.0001), "0.0001");
627 case(JsonValue::Number(0.00001), "0.00001");
628 case(JsonValue::Number(0.000001), "0.000001");
629 case(JsonValue::Number(0.0000001), "1e-7");
630 case(JsonValue::Number(1e-20), "1e-20");
631 case(JsonValue::Number(1e-40), "1e-40");
632 case(JsonValue::Number(1e-100), "1e-100");
633 case(JsonValue::Number(1e-200), "1e-200");
634 case(JsonValue::Number(1e-300), "1e-300");
635 case(JsonValue::Number(1e-323), "1e-323");
636 case(JsonValue::Number(1e-324), "0");
637 case(JsonValue::Number(10.0), "10");
638 case(JsonValue::Number(100.0), "100");
639 case(JsonValue::Number(1000.0), "1000");
640 case(JsonValue::Number(10000.0), "10000");
641 case(JsonValue::Number(100000.0), "100000");
642 case(JsonValue::Number(1000000.0), "1000000");
643 case(JsonValue::Number(1e10), "10000000000");
644 case(JsonValue::Number(1e20), "100000000000000000000");
645 case(JsonValue::Number(1e21), "1e+21");
646 case(JsonValue::Number(1e50), "1e+50");
647 case(JsonValue::Number(1e100), "1e+100");
648 case(JsonValue::Number(1e200), "1e+200");
649 case(JsonValue::Number(1e300), "1e+300");
650 case(JsonValue::Number(1e308), "1e+308");
651 case(JsonValue::Number(1.0), "1");
652 case(JsonValue::Number(1.5), "1.5");
653 case(JsonValue::Number(-42.42), "-42.42");
654 case(JsonValue::Number(0.123456789), "0.123456789");
655 case(JsonValue::Number(0.123456789123456789), "0.12345678912345678");
656 case(JsonValue::Number(0.123456789123456789123456789), "0.12345678912345678");
657 case(JsonValue::Number(1234567890.0), "1234567890");
658 case(JsonValue::Number(12345678901234567890.0), "12345678901234567000");
659 case(JsonValue::Number(123456789012345678901234567890.0), "1.2345678901234568e+29");
660 case(JsonValue::Number(1234567890123456789012345678901234567890.0), "1.2345678901234568e+39");
661 case(JsonValue::Number(1.5e21), "1.5e+21");
662 case(JsonValue::Number(1.5e-21), "1.5e-21");
663 case(JsonValue::Number(f64::NAN), "null");
664 case(JsonValue::Number(f64::INFINITY), "null");
665 case(JsonValue::Number(f64::NEG_INFINITY), "null");
666
667 case(JsonValue::String("".to_string()), "\"\"");
668 case(JsonValue::String(" ".to_string()), "\" \"");
669 case(
670 JsonValue::String("\u{0000}\u{0001}\u{0010}\u{0019}\u{0020}\u{0021}".to_string()),
671 "\"\\u0000\\u0001\\u0010\\u0019 !\""
672 );
673 case(
674 JsonValue::String("\u{0100}\u{0200}\u{0300}\u{0400}\u{0500}".to_string()),
675 "\"ĀȀ̀ЀԀ\""
676 );
677 case(
678 JsonValue::String("\u{1111}\u{2222}\u{3333}\u{4444}\u{5555}\u{6666}\u{7777}\u{8888}\u{9999}\u{aaaa}\u{bbbb}\u{cccc}".to_string()),
679 "\"ᄑ∢㌳䑄啕晦睷袈香ꪪ뮻쳌\""
680 );
681 case(JsonValue::String("привет".to_string()), "\"привет\"");
682 case(JsonValue::String("qwerty".to_string()), "\"qwerty\"");
683 case(JsonValue::String("line\n break".to_string()), "\"line\\n break\"");
684 case(JsonValue::String("quote\"test".to_string()), "\"quote\\\"test\"");
685 case(JsonValue::String("backslash\\".to_string()), "\"backslash\\\\\"");
686 case(JsonValue::String("tab\t char".to_string()), "\"tab\\t char\"");
687 case(JsonValue::String("newline\nand\t tab".to_string()), "\"newline\\nand\\t tab\"");
688 case(JsonValue::String("unicode\u{1F600}".to_string()), "\"unicode😀\"");
689
690 case(JsonValue::Array(vec![]), "[]");
691 case(
692 JsonValue::Array(vec![
693 JsonValue::Null,
694 JsonValue::Bool(true),
695 JsonValue::Number(3.14),
696 JsonValue::String("str".to_string())
697 ]),
698 "[null,true,3.14,\"str\"]"
699 );
700 case(
701 JsonValue::Array(vec![
702 JsonValue::Array(vec![]),
703 JsonValue::Array(vec![
704 JsonValue::Number(1.0),
705 JsonValue::Number(2.0),
706 JsonValue::Array(vec![
707 JsonValue::String("deep".to_string())
708 ])
709 ])
710 ]),
711 "[[],[1,2,[\"deep\"]]]"
712 );
713
714 case(JsonValue::Object(indexmap!{}), "{}");
715 case(
716 JsonValue::Object(indexmap!{
717 "null".to_string() => JsonValue::Null,
718 "bool".to_string() => JsonValue::Bool(false),
719 "num".to_string() => JsonValue::Number(42.0),
720 "str".to_string() => JsonValue::String("hello".to_string()),
721 }),
722 "{\"null\":null,\"bool\":false,\"num\":42,\"str\":\"hello\"}"
723 );
724 case(
725 JsonValue::Object(indexmap!{
726 "nested".to_string() => JsonValue::Object(indexmap!{
727 "arr".to_string() => JsonValue::Array(vec![
728 JsonValue::Number(1.0),
729 JsonValue::Number(2.0),
730 JsonValue::Object(indexmap!{
731 "deep".to_string() => JsonValue::Bool(true),
732 }),
733 ]),
734 }),
735 }),
736 "{\"nested\":{\"arr\":[1,2,{\"deep\":true}]}}"
737 );
738
739 case(
740 JsonValue::Array(vec![
741 JsonValue::Object(indexmap!{}),
742 JsonValue::Array(vec![]),
743 JsonValue::String("".to_string()),
744 JsonValue::Null,
745 JsonValue::Number(10.0),
746 JsonValue::Bool(true),
747 ]),
748 "[{},[],\"\",null,10,true]"
749 );
750 }
751
752 #[test]
753 fn test_parse() {
754 fn case(s: &str, o: Result<JsonValue, ParseError>) {
755 let o1 = parse(s);
756 let o2 = s.parse::<JsonValue>();
757 let o3 = JsonValue::from(s);
758 assert_eq!(o1, o);
759 assert_eq!(o2, o);
760 assert_eq!(o3, o);
761 }
762
763 case("", Err(ParseError::UnexpectedEndOfJsonInput));
766 case(" \t\r\n", Err(ParseError::UnexpectedEndOfJsonInput));
767 case("null null", Err(ParseError::UnexpectedNonWhitespaceAfterJson { ch: 'n', pos: 5 }));
768 case("|", Err(ParseError::UnexpectedToken { ch: '|', pos: 0 }));
769
770 case("null", Ok(JsonValue::Null));
773 case(" \t\r\nnull", Ok(JsonValue::Null));
774 case("null \t\r\n", Ok(JsonValue::Null));
775 case(" \t\r\nnull \t\r\n", Ok(JsonValue::Null));
776
777 case("true", Ok(JsonValue::Bool(true)));
781 case(" \t\r\ntrue", Ok(JsonValue::Bool(true)));
782 case("true \t\r\n", Ok(JsonValue::Bool(true)));
783 case(" \t\r\ntrue \t\r\n", Ok(JsonValue::Bool(true)));
784
785 case("false", Ok(JsonValue::Bool(false)));
787 case(" \t\r\nfalse", Ok(JsonValue::Bool(false)));
788 case("false \t\r\n", Ok(JsonValue::Bool(false)));
789 case(" \t\r\nfalse \t\r\n", Ok(JsonValue::Bool(false)));
790
791 case("\"", Err(ParseError::UnterminatedString { pos: 1 }));
795 case("\"abc", Err(ParseError::UnterminatedString { pos: 4 }));
796 case("\'", Err(ParseError::UnexpectedToken { ch: '\'', pos: 0 }));
797 case("\'\'", Err(ParseError::UnexpectedToken { ch: '\'', pos: 0 }));
798 case("\"\n\"", Err(ParseError::BadControlCharacter { pos: 1 }));
799 case("\"\\q\"", Err(ParseError::BadEscapedCharacter { pos: 2 }));
800 case("\"\\ux123\"", Err(ParseError::BadUnicodeEscape { pos: 3 }));
801 case("\"\\u1x23\"", Err(ParseError::BadUnicodeEscape { pos: 4 }));
802 case("\"\\u12x3\"", Err(ParseError::BadUnicodeEscape { pos: 5 }));
803 case("\"\\u123x\"", Err(ParseError::BadUnicodeEscape { pos: 6 }));
804 case("\"\\ud800\"", Err(ParseError::IllegalUnicodeEscapeOrSurrogate { pos: 1 }));
805 case("\"\\udbff\"", Err(ParseError::IllegalUnicodeEscapeOrSurrogate { pos: 1 }));
806
807 case("\"\"", Ok(JsonValue::String("".to_string())));
809 case("\" \"", Ok(JsonValue::String(" ".to_string())));
810 case("\"123\"", Ok(JsonValue::String("123".to_string())));
811 case("\"\\\"\\\\\\/\"", Ok(JsonValue::String("\"\\/".to_string())));
812 case("\"\\t\\n\\r\\b\\f\"", Ok(JsonValue::String("\t\n\r\x08\x14".to_string())));
813 case("\"\\u0041\"", Ok(JsonValue::String("A".to_string())));
814 case("\"\\u03A9\\u00A9\"", Ok(JsonValue::String("Ω©".to_string())));
815 case("\"Привет\"", Ok(JsonValue::String("Привет".to_string())));
816
817 case("+", Err(ParseError::UnexpectedToken { ch: '+', pos: 0 }));
821 case("+a", Err(ParseError::UnexpectedToken { ch: '+', pos: 0 }));
822 case("+0", Err(ParseError::UnexpectedToken { ch: '+', pos: 0 }));
823 case("+1", Err(ParseError::UnexpectedToken { ch: '+', pos: 0 }));
824 case("-", Err(ParseError::NoNumberAfterMinusSign { pos: 1 }));
825 case("-a", Err(ParseError::NoNumberAfterMinusSign { pos: 1 }));
826 case(".5", Err(ParseError::UnexpectedToken { ch: '.', pos: 0 }));
827 case("-.5", Err(ParseError::NoNumberAfterMinusSign { pos: 1 }));
828 case("00", Err(ParseError::UnexpectedNumber { pos: 1 }));
829 case("-00", Err(ParseError::UnexpectedNumber { pos: 2 }));
830 case("01", Err(ParseError::UnexpectedNumber { pos: 1 }));
831 case("-01", Err(ParseError::UnexpectedNumber { pos: 2 }));
832 case("001", Err(ParseError::UnexpectedNumber { pos: 1 }));
833 case("-001", Err(ParseError::UnexpectedNumber { pos: 2 }));
834 case("0.", Err(ParseError::UnterminatedFractionalNumber { pos: 2 }));
835 case("-0.", Err(ParseError::UnterminatedFractionalNumber { pos: 3 }));
836 case("1.", Err(ParseError::UnterminatedFractionalNumber { pos: 2 }));
837 case("-1.", Err(ParseError::UnterminatedFractionalNumber { pos: 3 }));
838 case("1.e10", Err(ParseError::UnterminatedFractionalNumber { pos: 2 }));
839 case("1e", Err(ParseError::ExponentPartIsMissingANumber { pos: 2 }));
840 case("1e+", Err(ParseError::ExponentPartIsMissingANumber { pos: 3 }));
841 case("1e-", Err(ParseError::ExponentPartIsMissingANumber { pos: 3 }));
842
843 case("0", Ok(JsonValue::Number(0.0)));
845 case("-0", Ok(JsonValue::Number(-0.0)));
846 case("0.0", Ok(JsonValue::Number(0.0)));
847 case("-0.0", Ok(JsonValue::Number(-0.0)));
848 case("1", Ok(JsonValue::Number(1.0)));
849 case("-1", Ok(JsonValue::Number(-1.0)));
850 case("1.0", Ok(JsonValue::Number(1.0)));
851 case("-1.0", Ok(JsonValue::Number(-1.0)));
852 case("1.000000", Ok(JsonValue::Number(1.0)));
853 case("-1.000000", Ok(JsonValue::Number(-1.0)));
854 case("123", Ok(JsonValue::Number(123.0)));
855 case("-123", Ok(JsonValue::Number(-123.0)));
856 case("123.000", Ok(JsonValue::Number(123.0)));
857 case("-123.000", Ok(JsonValue::Number(-123.0)));
858 case("0.5", Ok(JsonValue::Number(0.5)));
859 case("-0.5", Ok(JsonValue::Number(-0.5)));
860 case("123.456", Ok(JsonValue::Number(123.456)));
861 case("0e1", Ok(JsonValue::Number(0.0)));
862 case("-0E2", Ok(JsonValue::Number(-0.0)));
863 case("1e10", Ok(JsonValue::Number(1e10)));
864 case("1E10", Ok(JsonValue::Number(1e10)));
865 case("1e+10", Ok(JsonValue::Number(1e10)));
866 case("1e-10", Ok(JsonValue::Number(1e-10)));
867 case("0.1e+1", Ok(JsonValue::Number(0.1e1)));
868 case("-0.25E-2", Ok(JsonValue::Number(-0.25e-2)));
869 case("-123.456e-7", Ok(JsonValue::Number(-123.456e-7)));
870 case("1e308", Ok(JsonValue::Number(1e308)));
871 case("1e-308", Ok(JsonValue::Number(1e-308)));
872 case("1234567890123456789012345678901234567890", Ok(JsonValue::Number(1234567890123456789012345678901234567890.0)));
873 case("-1234567890123456789012345678901234567890", Ok(JsonValue::Number(-1234567890123456789012345678901234567890.0)));
874
875 case("[", Err(ParseError::UnexpectedEndOfArray));
879 case("]", Err(ParseError::UnexpectedToken { ch: ']', pos: 0 }));
880 case("[,", Err(ParseError::UnexpectedToken { ch: ',', pos: 1 }));
881 case("[,]", Err(ParseError::UnexpectedToken { ch: ',', pos: 1 }));
882 case("[0", Err(ParseError::UnexpectedEndOfArray));
883 case("0]", Err(ParseError::UnexpectedNonWhitespaceAfterJson { ch: ']', pos: 1 }));
884 case("[0,", Err(ParseError::UnexpectedEndOfJsonInput));
885 case("[0,]", Err(ParseError::UnexpectedToken { ch: ']', pos: 3 }));
886 case("[0,,]", Err(ParseError::UnexpectedToken { ch: ',', pos: 3 }));
887 case("[0 0]", Err(ParseError::UnexpectedCharacterAfterArrayElement { ch: '0', pos: 3 }));
888
889 case("[]", Ok(JsonValue::Array(vec![])));
891 case("[null]", Ok(JsonValue::Array(vec![JsonValue::Null])));
892 case("[true]", Ok(JsonValue::Array(vec![JsonValue::Bool(true)])));
893 case("[false]", Ok(JsonValue::Array(vec![JsonValue::Bool(false)])));
894 case("[0]", Ok(JsonValue::Array(vec![JsonValue::Number(0.0)])));
895 case("[\"Hello\"]", Ok(JsonValue::Array(vec![JsonValue::String("Hello".to_string())])));
896 case(
897 "[null, true, false, 0, \"Hello\"]",
898 Ok(JsonValue::Array(vec![
899 JsonValue::Null,
900 JsonValue::Bool(true),
901 JsonValue::Bool(false),
902 JsonValue::Number(0.0),
903 JsonValue::String("Hello".to_string()),
904 ])),
905 );
906 case(
907 "[[1, 2, 3], [[], null, true, false, 0, \"Hello\"], []]",
908 Ok(JsonValue::Array(vec![
909 JsonValue::Array(vec![
910 JsonValue::Number(1.0),
911 JsonValue::Number(2.0),
912 JsonValue::Number(3.0),
913 ]),
914 JsonValue::Array(vec![
915 JsonValue::Array(vec![]),
916 JsonValue::Null,
917 JsonValue::Bool(true),
918 JsonValue::Bool(false),
919 JsonValue::Number(0.0),
920 JsonValue::String("Hello".to_string()),
921 ]),
922 JsonValue::Array(vec![]),
923 ])),
924 );
925 case(
926 "[[], [[], [[], [[], []]]]]",
927 Ok(JsonValue::Array(vec![
928 JsonValue::Array(vec![]),
929 JsonValue::Array(vec![
930 JsonValue::Array(vec![]),
931 JsonValue::Array(vec![
932 JsonValue::Array(vec![]),
933 JsonValue::Array(vec![
934 JsonValue::Array(vec![]),
935 JsonValue::Array(vec![]),
936 ]),
937 ]),
938 ]),
939 ])),
940 );
941 case(
942 "[[[[[\"deep\"]]]]]",
943 Ok(JsonValue::Array(vec![
944 JsonValue::Array(vec![
945 JsonValue::Array(vec![
946 JsonValue::Array(vec![
947 JsonValue::Array(vec![
948 JsonValue::String("deep".to_string()),
949 ]),
950 ]),
951 ]),
952 ]),
953 ])),
954 );
955
956 case("{", Err(ParseError::UnexpectedEndOfObject));
960 case("}", Err(ParseError::UnexpectedToken { ch: '}', pos: 0 }));
961 case("{,", Err(ParseError::ExpectedPropertyName { pos: 1 }));
962 case("{,}", Err(ParseError::ExpectedPropertyName { pos: 1 }));
963 case("{0", Err(ParseError::ExpectedPropertyName { pos: 1 }));
964 case("0}", Err(ParseError::UnexpectedNonWhitespaceAfterJson { ch: '}', pos: 1 }));
965 case("{0,", Err(ParseError::ExpectedPropertyName { pos: 1 }));
966 case("{0,}", Err(ParseError::ExpectedPropertyName { pos: 1 }));
967 case("{0,,}", Err(ParseError::ExpectedPropertyName { pos: 1 }));
968 case("{0 0}", Err(ParseError::ExpectedPropertyName { pos: 1 }));
969 case("{0:0}", Err(ParseError::ExpectedPropertyName { pos: 1 }));
970 case("{0: 0}", Err(ParseError::ExpectedPropertyName { pos: 1 }));
971 case("{\"0\":", Err(ParseError::UnexpectedEndOfJsonInput));
972 case("{\"0\"::", Err(ParseError::UnexpectedToken { ch: ':', pos: 5 }));
973 case("{\"0\":}", Err(ParseError::UnexpectedToken { ch: '}', pos: 5 }));
974 case("{\"1\": 2,}", Err(ParseError::ExpectedPropertyName { pos: 8 }));
975
976 case("{}", Ok(JsonValue::Object(IndexMap::new())));
978 case("{\"1\": 2}", Ok(JsonValue::Object(indexmap!{"1".to_string() => JsonValue::Number(2.0)})));
979 case("{\"3\" :4}", Ok(JsonValue::Object(indexmap!{"3".to_string() => JsonValue::Number(4.0)})));
980 case("{\"5\" : 6}", Ok(JsonValue::Object(indexmap!{"5".to_string() => JsonValue::Number(6.0)})));
981 case("{\"true\" : false, \"false\" : false, \"undefined\" : null}", Ok(JsonValue::Object(indexmap!{
982 "true".to_string() => JsonValue::Bool(false),
983 "false".to_string() => JsonValue::Bool(false),
984 "undefined".to_string() => JsonValue::Null,
985 })));
986 case("{\"a\": null, \"b\": true, \"c\": false, \"d\": 1, \"e\": \"Hello\"}", Ok(JsonValue::Object(indexmap!{
987 "a".to_string() => JsonValue::Null,
988 "b".to_string() => JsonValue::Bool(true),
989 "c".to_string() => JsonValue::Bool(false),
990 "d".to_string() => JsonValue::Number(1.0),
991 "e".to_string() => JsonValue::String("Hello".to_string()),
992 })));
993 case("{\"nested\": {\"inner\": [1, 2, {\"deep\": false}]}}", Ok(JsonValue::Object(indexmap!{
994 "nested".to_string() => JsonValue::Object(indexmap!{
995 "inner".to_string() => JsonValue::Array(vec![
996 JsonValue::Number(1.0),
997 JsonValue::Number(2.0),
998 JsonValue::Object(indexmap!{
999 "deep".to_string() => JsonValue::Bool(false),
1000 }),
1001 ]),
1002 }),
1003 })));
1004 case("{\"arr\": [], \"obj\": {}}", Ok(JsonValue::Object(indexmap!{
1005 "arr".to_string() => JsonValue::Array(vec![]),
1006 "obj".to_string() => JsonValue::Object(indexmap!{}),
1007 })));
1008 case("{\"a\": [1, 2, {\"b\": [true, false, null]}, 3], \"c\": {\"d\": \"text\", \"e\": [[], [{}]]}}", Ok(JsonValue::Object(indexmap!{
1009 "a".to_string() => JsonValue::Array(vec![
1010 JsonValue::Number(1.0),
1011 JsonValue::Number(2.0),
1012 JsonValue::Object(indexmap!{
1013 "b".to_string() => JsonValue::Array(vec![
1014 JsonValue::Bool(true),
1015 JsonValue::Bool(false),
1016 JsonValue::Null,
1017 ]),
1018 }),
1019 JsonValue::Number(3.0),
1020 ]),
1021 "c".to_string() => JsonValue::Object(indexmap!{
1022 "d".to_string() => JsonValue::String("text".to_string()),
1023 "e".to_string() => JsonValue::Array(vec![
1024 JsonValue::Array(vec![]),
1025 JsonValue::Array(vec![
1026 JsonValue::Object(indexmap!{}),
1027 ]),
1028 ]),
1029 }),
1030 })));
1031 case("{\"num\": 123, \"bools\": [true, false], \"str\": \"value\", \"mix\": [{}, [], null]}", Ok(JsonValue::Object(indexmap!{
1032 "num".to_string() => JsonValue::Number(123.0),
1033 "bools".to_string() => JsonValue::Array(vec![
1034 JsonValue::Bool(true),
1035 JsonValue::Bool(false),
1036 ]),
1037 "str".to_string() => JsonValue::String("value".to_string()),
1038 "mix".to_string() => JsonValue::Array(vec![
1039 JsonValue::Object(indexmap!{}),
1040 JsonValue::Array(vec![]),
1041 JsonValue::Null,
1042 ]),
1043 })));
1044
1045 case(
1047 "[{},[],\"\",null,10,true]",
1048 Ok(JsonValue::Array(vec![
1049 JsonValue::Object(indexmap!{}),
1050 JsonValue::Array(vec![]),
1051 JsonValue::String("".to_string()),
1052 JsonValue::Null,
1053 JsonValue::Number(10.0),
1054 JsonValue::Bool(true),
1055 ]))
1056 );
1057 }
1058}