use super::placeholder;
use crate::ast::{JsonListElement, JsonObjectElement, JsonValue, SourceInfo, Template};
use crate::combinator::{ParseError as ParseErrorTrait, choice, non_recover};
use crate::parser::primitives::{boolean, hex_digit, literal, try_literal};
use crate::parser::template::EncodedString;
use crate::parser::{JsonErrorVariant, ParseError, ParseErrorKind, ParseResult, templatize};
use crate::reader::{Pos, Reader};
pub fn parse(reader: &mut Reader) -> ParseResult<JsonValue> {
choice(
&[
null_value,
boolean_value,
string_value,
number_value,
expression_value,
list_value,
object_value,
],
reader,
)
}
fn parse_in_json(reader: &mut Reader) -> ParseResult<JsonValue> {
if let Some(c) = reader.peek()
&& c == ','
{
let kind = ParseErrorKind::Json(JsonErrorVariant::EmptyElement);
return Err(ParseError::new(reader.cursor().pos, false, kind));
}
match parse(reader) {
Ok(r) => Ok(r),
Err(e) => match e {
ParseError {
recoverable: true, ..
} => {
let kind = ParseErrorKind::Json(JsonErrorVariant::ExpectingElement);
Err(ParseError::new(e.pos, false, kind))
}
_ => Err(ParseError::new(e.pos, false, e.kind)),
},
}
}
pub fn null_value(reader: &mut Reader) -> ParseResult<JsonValue> {
try_literal("null", reader)?;
Ok(JsonValue::Null)
}
pub fn boolean_value(reader: &mut Reader) -> ParseResult<JsonValue> {
let value = boolean(reader)?;
Ok(JsonValue::Boolean(value))
}
fn string_value(reader: &mut Reader) -> ParseResult<JsonValue> {
let template = string_template(reader)?;
Ok(JsonValue::String(template))
}
fn string_template(reader: &mut Reader) -> ParseResult<Template> {
try_literal("\"", reader)?;
let delimiter = Some('"');
let mut chars = vec![];
let start = reader.cursor();
loop {
if reader.peek() == Some('"') || reader.is_eof() {
break;
}
let char = any_char(reader)?;
chars.push(char);
}
let end = reader.cursor();
let encoded_string = EncodedString {
source_info: SourceInfo::new(start.pos, end.pos),
chars,
};
literal("\"", reader)?;
let elements = templatize(encoded_string)?;
let template = Template::new(delimiter, elements, SourceInfo::new(start.pos, end.pos));
Ok(template)
}
fn any_char(reader: &mut Reader) -> ParseResult<(char, String, Pos)> {
let start = reader.cursor();
match escape_char(reader) {
Ok(c) => Ok((c, reader.read_from(start.index), start.pos)),
Err(e) => {
if e.recoverable {
reader.seek(start);
match reader.read() {
None => {
let kind = ParseErrorKind::Expecting {
value: "char".to_string(),
};
Err(ParseError::new(start.pos, true, kind))
}
Some(c) => {
if ['\\', '\x08', '\n', '\x0c', '\r', '\t'].contains(&c) {
let kind = ParseErrorKind::Expecting {
value: "char".to_string(),
};
Err(ParseError::new(start.pos, true, kind))
} else {
Ok((c, reader.read_from(start.index), start.pos))
}
}
}
} else {
Err(e)
}
}
}
}
fn escape_char(reader: &mut Reader) -> ParseResult<char> {
try_literal("\\", reader)?;
let start = reader.cursor();
match reader.read() {
Some('"') => Ok('"'),
Some('\\') => Ok('\\'),
Some('/') => Ok('/'),
Some('b') => Ok('\x08'),
Some('n') => Ok('\n'),
Some('f') => Ok('\x0c'),
Some('r') => Ok('\r'),
Some('t') => Ok('\t'),
Some('u') => unicode(reader),
_ => Err(ParseError::new(
start.pos,
false,
ParseErrorKind::EscapeChar,
)),
}
}
fn unicode(reader: &mut Reader) -> ParseResult<char> {
let start = reader.cursor();
let cp1 = hex_value(reader)?;
let cp = if is_surrogate(cp1) {
literal("\\u", reader)?;
let start = reader.cursor();
let cp2 = hex_value(reader)?;
match cp_surrogate_pair(cp1, cp2) {
None => return Err(ParseError::new(start.pos, false, ParseErrorKind::Unicode)),
Some(cp) => cp,
}
} else {
cp1
};
let c = match char::from_u32(cp) {
None => return Err(ParseError::new(start.pos, false, ParseErrorKind::Unicode)),
Some(c) => c,
};
Ok(c)
}
const SURR1: u32 = 0xd800;
const SURR2: u32 = 0xdc00;
const SURR3: u32 = 0xe000;
const SURR_SELF: u32 = 0x10000;
fn is_surrogate(cp: u32) -> bool {
(SURR1..SURR3).contains(&cp)
}
fn cp_surrogate_pair(cp1: u32, cp2: u32) -> Option<u32> {
if (SURR1..SURR2).contains(&cp1) && (SURR2..SURR3).contains(&cp2) {
Some(((cp1 - SURR1) << 10) | ((cp2 - SURR2) + SURR_SELF))
} else {
None
}
}
fn hex_value(reader: &mut Reader) -> ParseResult<u32> {
let digit1 = non_recover(hex_digit, reader)?;
let digit2 = non_recover(hex_digit, reader)?;
let digit3 = non_recover(hex_digit, reader)?;
let digit4 = non_recover(hex_digit, reader)?;
let value = digit1 * (16 * 16 * 16) + digit2 * (16 * 16) + digit3 * 16 + digit4;
Ok(value)
}
pub fn number_value(reader: &mut Reader) -> ParseResult<JsonValue> {
let sign = match try_literal("-", reader) {
Err(_) => String::new(),
Ok(_) => "-".to_string(),
};
let int = integer(reader)?;
let frac = fraction(reader)?;
let exp = exponent(reader)?;
Ok(JsonValue::Number(format!("{sign}{int}{frac}{exp}")))
}
fn integer(reader: &mut Reader) -> ParseResult<String> {
let start = reader.cursor();
match try_literal("0", reader) {
Err(_) => {
let digits = reader.read_while(|c| c.is_ascii_digit());
if digits.is_empty() {
let kind = ParseErrorKind::Expecting {
value: "number".to_string(),
};
Err(ParseError::new(start.pos, true, kind))
} else {
Ok(digits)
}
}
Ok(_) => Ok("0".to_string()),
}
}
fn fraction(reader: &mut Reader) -> ParseResult<String> {
match try_literal(".", reader) {
Ok(_) => {
let digits = reader.read_while(|c| c.is_ascii_digit());
if digits.is_empty() {
let kind = ParseErrorKind::Expecting {
value: "digits".to_string(),
};
Err(ParseError::new(reader.cursor().pos, false, kind))
} else {
Ok(format!(".{digits}"))
}
}
Err(_) => Ok(String::new()),
}
}
fn exponent(reader: &mut Reader) -> ParseResult<String> {
if reader.peek() == Some('e') || reader.peek() == Some('E') {
reader.read();
let exponent_sign = match try_literal("-", reader) {
Ok(_) => "-".to_string(),
Err(_) => match try_literal("+", reader) {
Ok(_) => "+".to_string(),
Err(_) => String::new(),
},
};
let exponent_digits = reader.read_while(|c| c.is_ascii_digit());
Ok(format!("e{exponent_sign}{exponent_digits}"))
} else {
Ok(String::new())
}
}
fn expression_value(reader: &mut Reader) -> ParseResult<JsonValue> {
let exp = placeholder::parse(reader)?;
Ok(JsonValue::Placeholder(exp))
}
fn list_value(reader: &mut Reader) -> ParseResult<JsonValue> {
try_literal("[", reader)?;
let space0 = whitespace(reader);
let mut elements = vec![];
if reader.peek() != Some(']') {
let first_element = list_element(reader)?;
elements.push(first_element);
loop {
if reader.peek() == Some(']') {
break;
}
if reader.peek() != Some(',') {
break;
}
let save = reader.cursor();
literal(",", reader)?;
if reader.peek_if(|c| !is_whitespace(c)) == Some(']') {
let kind = ParseErrorKind::Json(JsonErrorVariant::TrailingComma);
return Err(ParseError::new(save.pos, false, kind));
}
let element = list_element(reader)?;
elements.push(element);
}
}
literal("]", reader)?;
Ok(JsonValue::List { space0, elements })
}
fn list_element(reader: &mut Reader) -> ParseResult<JsonListElement> {
let space0 = whitespace(reader);
let value = parse_in_json(reader)?;
let space1 = whitespace(reader);
Ok(JsonListElement {
space0,
value,
space1,
})
}
pub fn object_value(reader: &mut Reader) -> ParseResult<JsonValue> {
try_literal("{", reader)?;
let space0 = whitespace(reader);
let mut elements = vec![];
if reader.peek() != Some('}') {
let first_element = object_element(reader)?;
elements.push(first_element);
loop {
if reader.peek() == Some('}') {
break;
}
if reader.peek() != Some(',') {
break;
}
let save = reader.cursor();
literal(",", reader)?;
if reader.peek_if(|c| !is_whitespace(c)) == Some('}') {
let kind = ParseErrorKind::Json(JsonErrorVariant::TrailingComma);
return Err(ParseError::new(save.pos, false, kind));
}
let element = object_element(reader)?;
elements.push(element);
}
}
literal("}", reader)?;
Ok(JsonValue::Object { space0, elements })
}
fn key(reader: &mut Reader) -> ParseResult<Template> {
let name = string_template(reader).map_err(|e| e.to_non_recoverable())?;
Ok(name)
}
fn object_element(reader: &mut Reader) -> ParseResult<JsonObjectElement> {
let space0 = whitespace(reader);
let name = key(reader)?;
let space1 = whitespace(reader);
literal(":", reader)?;
let save = reader.cursor();
let space2 = whitespace(reader);
let next_char = reader.peek();
if next_char == Some('}') || next_char.is_none() {
let kind = ParseErrorKind::Json(JsonErrorVariant::EmptyElement);
return Err(ParseError::new(save.pos, false, kind));
}
let value = parse_in_json(reader)?;
let space3 = whitespace(reader);
Ok(JsonObjectElement {
space0,
name,
space1,
space2,
value,
space3,
})
}
fn is_whitespace(c: char) -> bool {
c == ' ' || c == '\t' || c == '\n' || c == '\r'
}
fn whitespace(reader: &mut Reader) -> String {
reader.read_while(is_whitespace)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ast::*;
use crate::reader::CharPos;
use crate::types::ToSource;
#[test]
fn test_parse_error() {
let mut reader = Reader::new("{ \"a\":\n}");
let error = parse(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 7 });
assert_eq!(
error.kind,
ParseErrorKind::Json(JsonErrorVariant::EmptyElement)
);
assert!(!error.recoverable);
let mut reader = Reader::new("[0,1,]");
let error = parse(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 5 });
assert_eq!(
error.kind,
ParseErrorKind::Json(JsonErrorVariant::TrailingComma),
);
assert!(!error.recoverable);
}
#[test]
fn test_null_value() {
let mut reader = Reader::new("null");
assert_eq!(null_value(&mut reader).unwrap(), JsonValue::Null);
assert_eq!(reader.cursor().index, CharPos(4));
let mut reader = Reader::new("true");
let error = null_value(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(
error.kind,
ParseErrorKind::Expecting {
value: "null".to_string()
}
);
assert!(error.recoverable);
}
#[test]
fn test_integer() {
let mut reader = Reader::new("0");
assert_eq!(integer(&mut reader).unwrap(), "0".to_string());
assert_eq!(reader.cursor().index, CharPos(1));
let mut reader = Reader::new("123");
assert_eq!(integer(&mut reader).unwrap(), "123".to_string());
assert_eq!(reader.cursor().index, CharPos(3));
let mut reader = Reader::new("0123");
assert_eq!(integer(&mut reader).unwrap(), "0".to_string());
assert_eq!(reader.cursor().index, CharPos(1));
}
#[test]
fn test_fraction() {
let mut reader = Reader::new(".5");
assert_eq!(fraction(&mut reader).unwrap(), ".5".to_string());
assert_eq!(reader.cursor().index, CharPos(2));
}
#[test]
fn test_exponent() {
let mut reader = Reader::new("e2");
assert_eq!(exponent(&mut reader).unwrap(), "e2".to_string());
assert_eq!(reader.cursor().index, CharPos(2));
}
#[test]
fn test_boolean_value() {
let mut reader = Reader::new("true");
assert_eq!(
boolean_value(&mut reader).unwrap(),
JsonValue::Boolean(true)
);
assert_eq!(reader.cursor().index, CharPos(4));
let mut reader = Reader::new("1");
let error = boolean_value(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(
error.kind,
ParseErrorKind::Expecting {
value: "true|false".to_string()
}
);
assert!(error.recoverable);
}
pub fn json_hello_world_value() -> JsonValue {
JsonValue::String(Template::new(
Some('"'),
vec![
TemplateElement::String {
value: "Hello ".to_string(),
source: "Hello\\u0020".to_source(),
},
TemplateElement::Placeholder(Placeholder {
space0: Whitespace {
value: String::new(),
source_info: SourceInfo::new(Pos::new(1, 15), Pos::new(1, 15)),
},
expr: Expr {
kind: ExprKind::Variable(Variable {
name: "name".to_string(),
source_info: SourceInfo::new(Pos::new(1, 15), Pos::new(1, 19)),
}),
source_info: SourceInfo::new(Pos::new(1, 15), Pos::new(1, 19)),
},
space1: Whitespace {
value: String::new(),
source_info: SourceInfo::new(Pos::new(1, 19), Pos::new(1, 19)),
},
}),
TemplateElement::String {
value: "!".to_string(),
source: "!".to_source(),
},
],
SourceInfo::new(Pos::new(1, 2), Pos::new(1, 22)),
))
}
#[test]
fn test_string_value() {
let mut reader = Reader::new("\"\"");
assert_eq!(
string_value(&mut reader).unwrap(),
JsonValue::String(Template::new(
Some('"'),
vec![],
SourceInfo::new(Pos::new(1, 2), Pos::new(1, 2)),
))
);
assert_eq!(reader.cursor().index, CharPos(2));
let mut reader = Reader::new("\"Hello\\u0020{{name}}!\"");
assert_eq!(string_value(&mut reader).unwrap(), json_hello_world_value());
assert_eq!(reader.cursor().index, CharPos(22));
let mut reader = Reader::new("\"{}\"");
assert_eq!(
string_value(&mut reader).unwrap(),
JsonValue::String(Template::new(
Some('"'),
vec![TemplateElement::String {
value: "{}".to_string(),
source: "{}".to_source(),
}],
SourceInfo::new(Pos::new(1, 2), Pos::new(1, 4)),
))
);
assert_eq!(reader.cursor().index, CharPos(4));
}
#[test]
fn test_string_value_error() {
let mut reader = Reader::new("1");
let error = string_value(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(
error.kind,
ParseErrorKind::Expecting {
value: "\"".to_string()
}
);
assert!(error.recoverable);
let mut reader = Reader::new("\"1");
let error = string_value(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 3 });
assert_eq!(
error.kind,
ParseErrorKind::Expecting {
value: "\"".to_string()
}
);
assert!(!error.recoverable);
let mut reader = Reader::new("\"{{x\"");
let error = string_value(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 5 });
assert_eq!(
error.kind,
ParseErrorKind::Expecting {
value: "}}".to_string()
}
);
assert!(!error.recoverable);
}
#[test]
fn test_any_char() {
let mut reader = Reader::new("a");
assert_eq!(
any_char(&mut reader).unwrap(),
('a', "a".to_string(), Pos { line: 1, column: 1 })
);
assert_eq!(reader.cursor().index, CharPos(1));
let mut reader = Reader::new(" ");
assert_eq!(
any_char(&mut reader).unwrap(),
(' ', " ".to_string(), Pos { line: 1, column: 1 })
);
assert_eq!(reader.cursor().index, CharPos(1));
let mut reader = Reader::new("\\u0020 ");
assert_eq!(
any_char(&mut reader).unwrap(),
(' ', "\\u0020".to_string(), Pos { line: 1, column: 1 })
);
assert_eq!(reader.cursor().index, CharPos(6));
let mut reader = Reader::new("\\t");
assert_eq!(
any_char(&mut reader).unwrap(),
('\t', "\\t".to_string(), Pos { line: 1, column: 1 })
);
assert_eq!(reader.cursor().index, CharPos(2));
let mut reader = Reader::new("#");
assert_eq!(
any_char(&mut reader).unwrap(),
('#', "#".to_string(), Pos { line: 1, column: 1 })
);
assert_eq!(reader.cursor().index, CharPos(1));
}
#[test]
fn test_any_char_error() {
let mut reader = Reader::new("");
let error = any_char(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert!(error.recoverable);
let mut reader = Reader::new("\t");
let error = any_char(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert!(error.recoverable);
}
#[test]
fn test_escape_char() {
let mut reader = Reader::new("\\n");
assert_eq!(escape_char(&mut reader).unwrap(), '\n');
assert_eq!(reader.cursor().index, CharPos(2));
let mut reader = Reader::new("\\u000a");
assert_eq!(escape_char(&mut reader).unwrap(), '\n');
assert_eq!(reader.cursor().index, CharPos(6));
let mut reader = Reader::new("x");
let error = escape_char(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(
error.kind,
ParseErrorKind::Expecting {
value: "\\".to_string()
}
);
assert!(error.recoverable);
assert_eq!(reader.cursor().index, CharPos(0));
}
#[test]
fn test_unicode() {
let mut reader = Reader::new("000a");
assert_eq!(unicode(&mut reader).unwrap(), '\n');
assert_eq!(reader.cursor().index, CharPos(4));
let mut reader = Reader::new("c350");
assert_eq!(unicode(&mut reader).unwrap(), '썐');
assert_eq!(reader.cursor().index, CharPos(4));
let mut reader = Reader::new("d83c\\udf78");
assert_eq!(unicode(&mut reader).unwrap(), '🍸');
assert_eq!(reader.cursor().index, CharPos(10));
let mut reader = Reader::new("d800");
let error = unicode(&mut reader).unwrap_err();
assert_eq!(error.pos, Pos { line: 1, column: 5 });
assert_eq!(
error.kind,
ParseErrorKind::Expecting {
value: "\\u".to_string()
}
);
assert!(!error.recoverable);
let mut reader = Reader::new("d800\\ud800");
let error = unicode(&mut reader).unwrap_err();
assert_eq!(error.pos, Pos { line: 1, column: 7 });
assert_eq!(error.kind, ParseErrorKind::Unicode);
assert!(!error.recoverable);
}
#[test]
fn test_hex_value() {
let mut reader = Reader::new("0020x");
assert_eq!(hex_value(&mut reader).unwrap(), 32);
let mut reader = Reader::new("d800");
assert_eq!(hex_value(&mut reader).unwrap(), 55296);
let mut reader = Reader::new("x");
let error = hex_value(&mut reader).unwrap_err();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(error.kind, ParseErrorKind::HexDigit);
assert!(!error.recoverable);
}
#[test]
fn test_number_value() {
let mut reader = Reader::new("100");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("100".to_string())
);
assert_eq!(reader.cursor().index, CharPos(3));
let mut reader = Reader::new("1.333");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("1.333".to_string())
);
assert_eq!(reader.cursor().index, CharPos(5));
let mut reader = Reader::new("-1");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("-1".to_string())
);
assert_eq!(reader.cursor().index, CharPos(2));
let mut reader = Reader::new("00");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("0".to_string())
);
assert_eq!(reader.cursor().index, CharPos(1));
let mut reader = Reader::new("1e0");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("1e0".to_string())
);
assert_eq!(reader.cursor().index, CharPos(3));
let mut reader = Reader::new("1e005");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("1e005".to_string())
);
assert_eq!(reader.cursor().index, CharPos(5));
let mut reader = Reader::new("1e-005");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("1e-005".to_string())
);
assert_eq!(reader.cursor().index, CharPos(6));
}
#[test]
fn test_number_value_error() {
let mut reader = Reader::new("true");
let error = number_value(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(
error.kind,
ParseErrorKind::Expecting {
value: "number".to_string()
}
);
assert!(error.recoverable);
let mut reader = Reader::new("1.x");
let error = number_value(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 3 });
assert_eq!(
error.kind,
ParseErrorKind::Expecting {
value: "digits".to_string()
}
);
assert!(!error.recoverable);
}
#[test]
fn test_expression_value() {
let mut reader = Reader::new("{{n}}");
assert_eq!(
expression_value(&mut reader).unwrap(),
JsonValue::Placeholder(Placeholder {
space0: Whitespace {
value: String::new(),
source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 3))
},
expr: Expr {
kind: ExprKind::Variable(Variable {
name: "n".to_string(),
source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 4))
}),
source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 4))
},
space1: Whitespace {
value: String::new(),
source_info: SourceInfo::new(Pos::new(1, 4), Pos::new(1, 4))
}
})
);
assert_eq!(reader.cursor().index, CharPos(5));
}
#[test]
fn test_list_value() {
let mut reader = Reader::new("[]");
assert_eq!(
list_value(&mut reader).unwrap(),
JsonValue::List {
space0: String::new(),
elements: vec![]
}
);
assert_eq!(reader.cursor().index, CharPos(2));
let mut reader = Reader::new("[ ]");
assert_eq!(
list_value(&mut reader).unwrap(),
JsonValue::List {
space0: " ".to_string(),
elements: vec![]
}
);
assert_eq!(reader.cursor().index, CharPos(3));
let mut reader = Reader::new("[true, false]");
assert_eq!(
list_value(&mut reader).unwrap(),
JsonValue::List {
space0: String::new(),
elements: vec![
JsonListElement {
space0: String::new(),
value: JsonValue::Boolean(true),
space1: String::new(),
},
JsonListElement {
space0: String::from(" "),
value: JsonValue::Boolean(false),
space1: String::new(),
}
],
}
);
assert_eq!(reader.cursor().index, CharPos(13));
}
#[test]
fn test_list_error() {
let mut reader = Reader::new("true");
let error = list_value(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(
error.kind,
ParseErrorKind::Expecting {
value: "[".to_string()
}
);
assert!(error.recoverable);
let mut reader = Reader::new("[1, 2,]");
let error = list_value(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 6 });
assert_eq!(
error.kind,
ParseErrorKind::Json(JsonErrorVariant::TrailingComma),
);
assert!(!error.recoverable);
}
#[test]
fn test_list_element() {
let mut reader = Reader::new("true");
assert_eq!(
list_element(&mut reader).unwrap(),
JsonListElement {
space0: String::new(),
value: JsonValue::Boolean(true),
space1: String::new(),
}
);
assert_eq!(reader.cursor().index, CharPos(4));
}
#[test]
fn test_object_value() {
let mut reader = Reader::new("{}");
assert_eq!(
object_value(&mut reader).unwrap(),
JsonValue::Object {
space0: String::new(),
elements: vec![]
}
);
assert_eq!(reader.cursor().index, CharPos(2));
let mut reader = Reader::new("{ }");
assert_eq!(
object_value(&mut reader).unwrap(),
JsonValue::Object {
space0: " ".to_string(),
elements: vec![]
}
);
assert_eq!(reader.cursor().index, CharPos(3));
let mut reader = Reader::new("{\n \"a\": true\n}");
assert_eq!(
object_value(&mut reader).unwrap(),
JsonValue::Object {
space0: "\n ".to_string(),
elements: vec![JsonObjectElement {
space0: String::new(),
name: Template::new(
Some('"'),
vec![TemplateElement::String {
value: "a".to_string(),
source: "a".to_source()
}],
SourceInfo::new(Pos::new(2, 4), Pos::new(2, 5))
),
space1: String::new(),
space2: " ".to_string(),
value: JsonValue::Boolean(true),
space3: "\n".to_string(),
}],
}
);
assert_eq!(reader.cursor().index, CharPos(15));
let mut reader = Reader::new("true");
let error = object_value(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(
error.kind,
ParseErrorKind::Expecting {
value: "{".to_string()
}
);
assert!(error.recoverable);
}
#[test]
fn test_object_error() {
let mut reader = Reader::new("{ \"a\":\n}");
let error = object_value(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 7 });
assert_eq!(
error.kind,
ParseErrorKind::Json(JsonErrorVariant::EmptyElement)
);
assert!(!error.recoverable);
}
#[test]
fn test_object_element() {
let mut reader = Reader::new("\"a\": true");
assert_eq!(
object_element(&mut reader).unwrap(),
JsonObjectElement {
space0: String::new(),
name: Template::new(
Some('"'),
vec![TemplateElement::String {
value: "a".to_string(),
source: "a".to_source()
}],
SourceInfo::new(Pos::new(1, 2), Pos::new(1, 3))
),
space1: String::new(),
space2: " ".to_string(),
value: JsonValue::Boolean(true),
space3: String::new(),
}
);
assert_eq!(reader.cursor().index, CharPos(9));
}
#[test]
fn test_object_element_error() {
let mut reader = Reader::new(":");
let error = object_element(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 1 });
assert_eq!(
error.kind,
ParseErrorKind::Expecting {
value: "\"".to_string()
}
);
assert!(!error.recoverable);
let mut reader = Reader::new("\"name\":\n");
let error = object_element(&mut reader).err().unwrap();
assert_eq!(error.pos, Pos { line: 1, column: 8 });
assert_eq!(
error.kind,
ParseErrorKind::Json(JsonErrorVariant::EmptyElement),
);
assert!(!error.recoverable);
}
#[test]
fn test_whitespace() {
let mut reader = Reader::new("");
assert_eq!(whitespace(&mut reader), String::new());
assert_eq!(reader.cursor().index, CharPos(0));
let mut reader = Reader::new(" x");
assert_eq!(whitespace(&mut reader), " ".to_string());
assert_eq!(reader.cursor().index, CharPos(1));
let mut reader = Reader::new("\n x");
assert_eq!(whitespace(&mut reader), "\n ".to_string());
assert_eq!(reader.cursor().index, CharPos(3));
}
}