use crate::ast::{JsonListElement, JsonObjectElement, JsonValue, Pos, SourceInfo, Template};
use crate::parser::combinators::*;
use crate::parser::error::*;
use crate::parser::primitives::*;
use crate::parser::reader::*;
use crate::parser::template::*;
use crate::parser::{expr, ParseResult};
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() {
if c == ',' {
let inner = ParseError::Json(JsonErrorVariant::EmptyElement);
return Err(Error::new(reader.state.pos, false, inner));
}
}
match parse(reader) {
Ok(r) => Ok(r),
Err(e) => match e {
Error {
recoverable: true, ..
} => {
let inner = ParseError::Json(JsonErrorVariant::ExpectingElement);
Err(Error::new(e.pos, false, inner))
}
_ => Err(Error::new(e.pos, false, e.inner)),
},
}
}
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.state.pos;
loop {
if reader.peek() == Some('"') || reader.is_eof() {
break;
}
let char = any_char(reader)?;
chars.push(char);
}
let end = reader.state.pos;
let encoded_string = EncodedString {
source_info: SourceInfo { start, end },
chars,
};
literal("\"", reader)?;
let elements = templatize(encoded_string)?;
let template = Template {
delimiter,
elements,
source_info: SourceInfo { start, end },
};
Ok(template)
}
fn any_char(reader: &mut Reader) -> ParseResult<(char, String, Pos)> {
let start = reader.state;
match escape_char(reader) {
Ok(c) => Ok((c, reader.peek_back(start.cursor), start.pos)),
Err(e) => {
if e.recoverable {
reader.state = start;
match reader.read() {
None => {
let inner = ParseError::Expecting {
value: "char".to_string(),
};
Err(Error::new(start.pos, true, inner))
}
Some(c) => {
if ['\\', '\x08', '\n', '\x0c', '\r', '\t'].contains(&c) {
let inner = ParseError::Expecting {
value: "char".to_string(),
};
Err(Error::new(start.pos, true, inner))
} else {
Ok((c, reader.peek_back(start.cursor), start.pos))
}
}
}
} else {
Err(e)
}
}
}
}
fn escape_char(reader: &mut Reader) -> ParseResult<char> {
try_literal("\\", reader)?;
let start = reader.state;
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(Error::new(start.pos, false, ParseError::EscapeChar)),
}
}
fn unicode(reader: &mut Reader) -> ParseResult<char> {
let start = reader.state.pos;
let cp1 = hex_value(reader)?;
let cp = if is_surrogate(cp1) {
literal("\\u", reader)?;
let start = reader.state.pos;
let cp2 = hex_value(reader)?;
match cp_surrogate_pair(cp1, cp2) {
None => return Err(Error::new(start, false, ParseError::Unicode)),
Some(cp) => cp,
}
} else {
cp1
};
let c = match char::from_u32(cp) {
None => return Err(Error::new(start, false, ParseError::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 = nonrecover(hex_digit, reader)?;
let digit2 = nonrecover(hex_digit, reader)?;
let digit3 = nonrecover(hex_digit, reader)?;
let digit4 = nonrecover(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 start = reader.state;
let sign = match try_literal("-", reader) {
Err(_) => String::new(),
Ok(_) => "-".to_string(),
};
let integer = match try_literal("0", reader) {
Err(_) => {
let digits = reader.read_while(|c| c.is_ascii_digit());
if digits.is_empty() {
let inner = ParseError::Expecting {
value: "number".to_string(),
};
return Err(Error::new(start.pos, true, inner));
} else {
digits
}
}
Ok(_) => "0".to_string(),
};
let fraction = match try_literal(".", reader) {
Ok(_) => {
let digits = reader.read_while(|c| c.is_ascii_digit());
if digits.is_empty() {
let inner = ParseError::Expecting {
value: "digits".to_string(),
};
return Err(Error::new(reader.state.pos, false, inner));
} else {
format!(".{digits}")
}
}
Err(_) => String::new(),
};
let exponent = 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());
format!("e{exponent_sign}{exponent_digits}")
} else {
String::new()
};
Ok(JsonValue::Number(format!(
"{sign}{integer}{fraction}{exponent}"
)))
}
fn expression_value(reader: &mut Reader) -> ParseResult<JsonValue> {
let exp = expr::parse(reader)?;
Ok(JsonValue::Expression(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.state.pos;
literal(",", reader)?;
if reader.peek_ignoring_whitespace() == Some(']') {
let inner = ParseError::Json(JsonErrorVariant::TrailingComma);
return Err(Error::new(save, false, inner));
}
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.state.pos;
literal(",", reader)?;
if reader.peek_ignoring_whitespace() == Some('}') {
let inner = ParseError::Json(JsonErrorVariant::TrailingComma);
return Err(Error::new(save, false, inner));
}
let element = object_element(reader)?;
elements.push(element);
}
}
literal("}", reader)?;
Ok(JsonValue::Object { space0, elements })
}
fn key(reader: &mut Reader) -> ParseResult<Template> {
let save = reader.state;
let name = string_template(reader).map_err(|e| e.non_recoverable())?;
if name.elements.is_empty() {
let inner = ParseError::Json(JsonErrorVariant::EmptyElement);
Err(Error::new(save.pos, false, inner))
} else {
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.state.pos;
let space2 = whitespace(reader);
let next_char = reader.peek();
if next_char == Some('}') || next_char.is_none() {
let inner = ParseError::Json(JsonErrorVariant::EmptyElement);
return Err(Error::new(save, false, inner));
}
let value = parse_in_json(reader)?;
let space3 = whitespace(reader);
Ok(JsonObjectElement {
space0,
name,
space1,
space2,
value,
space3,
})
}
fn whitespace(reader: &mut Reader) -> String {
reader.read_while(|c| *c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ast::*;
#[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.inner,
ParseError::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.inner,
ParseError::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.state.cursor, 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.inner,
ParseError::Expecting {
value: "null".to_string()
}
);
assert!(error.recoverable);
}
#[test]
fn test_boolean_value() {
let mut reader = Reader::new("true");
assert_eq!(
boolean_value(&mut reader).unwrap(),
JsonValue::Boolean(true)
);
assert_eq!(reader.state.cursor, 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.inner,
ParseError::Expecting {
value: "true|false".to_string()
}
);
assert!(error.recoverable);
}
pub fn json_hello_world_value() -> JsonValue {
JsonValue::String(Template {
delimiter: Some('"'),
elements: vec![
TemplateElement::String {
value: "Hello ".to_string(),
encoded: "Hello\\u0020".to_string(),
},
TemplateElement::Expression(Expr {
space0: Whitespace {
value: String::new(),
source_info: SourceInfo::new(Pos::new(1, 15), Pos::new(1, 15)),
},
variable: Variable {
name: "name".to_string(),
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(),
encoded: "!".to_string(),
},
],
source_info: 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 {
delimiter: Some('"'),
elements: vec![],
source_info: SourceInfo::new(Pos::new(1, 2), Pos::new(1, 2)),
})
);
assert_eq!(reader.state.cursor, 2);
let mut reader = Reader::new("\"Hello\\u0020{{name}}!\"");
assert_eq!(string_value(&mut reader).unwrap(), json_hello_world_value());
assert_eq!(reader.state.cursor, 22);
let mut reader = Reader::new("\"{}\"");
assert_eq!(
string_value(&mut reader).unwrap(),
JsonValue::String(Template {
delimiter: Some('"'),
elements: vec![TemplateElement::String {
value: "{}".to_string(),
encoded: "{}".to_string(),
}],
source_info: SourceInfo::new(Pos::new(1, 2), Pos::new(1, 4)),
})
);
assert_eq!(reader.state.cursor, 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.inner,
ParseError::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.inner,
ParseError::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.inner,
ParseError::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.state.cursor, 1);
let mut reader = Reader::new(" ");
assert_eq!(
any_char(&mut reader).unwrap(),
(' ', " ".to_string(), Pos { line: 1, column: 1 })
);
assert_eq!(reader.state.cursor, 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.state.cursor, 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.state.cursor, 2);
let mut reader = Reader::new("#");
assert_eq!(
any_char(&mut reader).unwrap(),
('#', "#".to_string(), Pos { line: 1, column: 1 })
);
assert_eq!(reader.state.cursor, 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.state.cursor, 2);
let mut reader = Reader::new("\\u000a");
assert_eq!(escape_char(&mut reader).unwrap(), '\n');
assert_eq!(reader.state.cursor, 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.inner,
ParseError::Expecting {
value: "\\".to_string()
}
);
assert!(error.recoverable);
assert_eq!(reader.state.cursor, 0);
}
#[test]
fn test_unicode() {
let mut reader = Reader::new("000a");
assert_eq!(unicode(&mut reader).unwrap(), '\n');
assert_eq!(reader.state.cursor, 4);
let mut reader = Reader::new("c350");
assert_eq!(unicode(&mut reader).unwrap(), '썐');
assert_eq!(reader.state.cursor, 4);
let mut reader = Reader::new("d83c\\udf78");
assert_eq!(unicode(&mut reader).unwrap(), '🍸');
assert_eq!(reader.state.cursor, 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.inner,
ParseError::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.inner, ParseError::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.inner, ParseError::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.state.cursor, 3);
let mut reader = Reader::new("1.333");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("1.333".to_string())
);
assert_eq!(reader.state.cursor, 5);
let mut reader = Reader::new("-1");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("-1".to_string())
);
assert_eq!(reader.state.cursor, 2);
let mut reader = Reader::new("00");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("0".to_string())
);
assert_eq!(reader.state.cursor, 1);
let mut reader = Reader::new("1e0");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("1e0".to_string())
);
assert_eq!(reader.state.cursor, 3);
let mut reader = Reader::new("1e005");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("1e005".to_string())
);
assert_eq!(reader.state.cursor, 5);
let mut reader = Reader::new("1e-005");
assert_eq!(
number_value(&mut reader).unwrap(),
JsonValue::Number("1e-005".to_string())
);
assert_eq!(reader.state.cursor, 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.inner,
ParseError::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.inner,
ParseError::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::Expression(Expr {
space0: Whitespace {
value: String::new(),
source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 3))
},
variable: Variable {
name: "n".to_string(),
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.state.cursor, 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.state.cursor, 2);
let mut reader = Reader::new("[ ]");
assert_eq!(
list_value(&mut reader).unwrap(),
JsonValue::List {
space0: " ".to_string(),
elements: vec![]
}
);
assert_eq!(reader.state.cursor, 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.state.cursor, 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.inner,
ParseError::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.inner,
ParseError::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.state.cursor, 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.state.cursor, 2);
let mut reader = Reader::new("{ }");
assert_eq!(
object_value(&mut reader).unwrap(),
JsonValue::Object {
space0: " ".to_string(),
elements: vec![]
}
);
assert_eq!(reader.state.cursor, 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 {
delimiter: Some('"'),
elements: vec![TemplateElement::String {
value: "a".to_string(),
encoded: "a".to_string()
}],
source_info: 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.state.cursor, 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.inner,
ParseError::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.inner,
ParseError::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 {
delimiter: Some('"'),
elements: vec![TemplateElement::String {
value: "a".to_string(),
encoded: "a".to_string()
}],
source_info: 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.state.cursor, 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.inner,
ParseError::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.inner,
ParseError::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.state.cursor, 0);
let mut reader = Reader::new(" x");
assert_eq!(whitespace(&mut reader), " ".to_string());
assert_eq!(reader.state.cursor, 1);
let mut reader = Reader::new("\n x");
assert_eq!(whitespace(&mut reader), "\n ".to_string());
assert_eq!(reader.state.cursor, 3);
}
}