///|
/// A parsed JSON value. `Number` retains its input token until the JCS number
/// serializer is applied; this prevents an early, host-specific conversion.
pub enum JsonValue {
Null
Bool(Bool)
Number(String)
String(String)
Array(Array[JsonValue])
Object(Array[(String, JsonValue)])
}
///|
/// A source-positioned reason why strict JSON parsing failed.
pub enum ParseError {
UnexpectedEnd(Int)
UnexpectedCharacter(Int, Char)
Expected(Int, String)
InvalidEscape(Int, String)
InvalidNumber(Int, String)
DuplicateKey(Int, String)
TrailingContent(Int)
}
///|
/// A value that cannot be represented by JCS canonical JSON.
pub enum CanonicalError {
InvalidNumber(String, String)
NonFiniteNumber(String)
}
///|
pub fn CanonicalError::message(self : CanonicalError) -> String {
match self {
InvalidNumber(value, reason) =>
"cannot canonicalize number '" + value + "': " + reason
NonFiniteNumber(value) =>
"number '" + value + "' is outside IEEE-754 finite range"
}
}
///|
pub fn ParseError::message(self : ParseError) -> String {
match self {
UnexpectedEnd(position) =>
"unexpected end of JSON at character " + position.to_string()
UnexpectedCharacter(position, char) =>
"unexpected character '" +
char.to_string() +
"' at character " +
position.to_string()
Expected(position, expected) =>
"expected " + expected + " at character " + position.to_string()
InvalidEscape(position, reason) =>
"invalid string escape at character " +
position.to_string() +
": " +
reason
InvalidNumber(position, reason) =>
"invalid number at character " + position.to_string() + ": " + reason
DuplicateKey(position, key) =>
"duplicate object key '" + key + "' at character " + position.to_string()
TrailingContent(position) =>
"trailing content at character " + position.to_string()
}
}
///|
priv struct Parser {
chars : Array[Char]
mut position : Int
}
///|
fn Parser::new(input : String) -> Parser {
let chars : Array[Char] = []
for char in input {
chars.push(char)
}
{ chars, position: 0 }
}