Skip to main content

p_json/
lib.rs

1// p-json — Petr Sabanov's JSON implementation
2// Copyright (C) © 2025  Petr Aleksandrovich Sabanov
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU Lesser General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU Lesser General Public License for more details.
13//
14// You should have received a copy of the GNU Lesser General Public License
15// along with this program.  If not, see <https://www.gnu.org/licenses/>.
16
17//! ## Examples
18//!
19//! ### Parsing
20//!
21//! ```
22//! use p_json::{JsonValue, parse};
23//! use indexmap::{IndexMap, indexmap};
24//!
25//! fn main() {
26//! 	let text = r#"{"id":123,"name":"Alice","active":true}"#;
27//! 	let json = parse(text).unwrap();
28//!
29//! 	assert_eq!(json, JsonValue::Object(indexmap!{
30//! 		"id".to_string() => JsonValue::Number(123.0),
31//! 		"name".to_string() => JsonValue::String("Alice".to_string()),
32//! 		"active".to_string() => JsonValue::Bool(true),
33//! 	}));
34//! }
35//! ```
36//!
37//! ### Stringification
38//!
39//! ```
40//! use p_json::{JsonValue, stringify};
41//! use indexmap::{IndexMap, indexmap};
42//!
43//! fn main() {
44//! 	let mut json = JsonValue::Object(indexmap!{
45//! 		"id".to_string() => JsonValue::Number(123.0),
46//! 		"name".to_string() => JsonValue::String("Alice".to_string()),
47//! 		"active".to_string() => JsonValue::Bool(true),
48//! 	});
49//!
50//! 	let text = stringify(&json);
51//! 	assert_eq!(text, r#"{"id":123,"name":"Alice","active":true}"#);
52//! }
53//! ```
54//!
55//! ### Validation
56//!
57//! ```
58//! fn main() {
59//! 	let valid = r#"{"key": "value"}"#;
60//! 	let invalid = r#"{"key": "value""#;
61//!
62//! 	assert!(p_json::parse(valid).is_ok());
63//! 	assert!(p_json::parse(invalid).is_err());
64//! }
65//! ```
66
67use 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	// whole part
507	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	// fraction
528	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	// exponent
543	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		// I. SPECIAL
764
765		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		// II. NULL
771
772		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		// II. BOOL
778
779		// II.i true
780		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		// II.ii false
786		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		// III. STRING
792
793		// III.i invalid
794		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		// III.ii valid
808		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		// IV. NUMBER
818
819		// IV.i invalid
820		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		// IV.ii valid
844		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		// V. ARRAY
876
877		// V.i invalid
878		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		// V.ii valid
890		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		// VI. OBJECT
957
958		// VI.i invalid
959		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		// VI.ii valid
977		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		// VII. ALL
1046		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}