///|
let depth_limit_label = "JSON nesting depth limit"
///|
let string_limit_label = "JSON string character limit"
///|
let array_limit_label = "JSON array item limit"
///|
let object_limit_label = "JSON object member limit"
///|
fn join(parts : Array[String]) -> String {
let chars = []
for part in parts {
for char in part {
chars.push(char)
}
}
String::from_array(chars[:])
}
///|
fn raw_char(character : Char, expected~ : String) -> @parsec.Parser[Char, Char] {
@parsec.Parser::token(character, expected~)
}
///|
fn json_whitespace() -> @parsec.Parser[Char, Unit] {
@parsec.Parser::satisfy("JSON whitespace", char => {
char == ' ' || char == '\t' || char == '\n' || char == '\r'
})
.many()
.ignore()
}
///|
fn token(character : Char, expected~ : String) -> @parsec.Parser[Char, Char] {
raw_char(character, expected~).then_left(json_whitespace())
}
///|
fn text(value : String, expected~ : String) -> @parsec.Parser[Char, Unit] {
let mut parser : @parsec.Parser[Char, Unit] = @parsec.Parser::pure(())
for character in value {
parser = parser.then_right(raw_char(character, expected~).ignore())
}
parser.then_left(json_whitespace())
}
///|
fn[T, A] fail_at(label : String) -> @parsec.Parser[T, A] {
@parsec.Parser::position().flat_map(offset => {
@parsec.Parser::fail(Expected(label~, offset~))
})
}
///|
fn hex_digit() -> @parsec.Parser[Char, Int] {
@parsec.Parser::satisfy("hexadecimal digit", char => {
(char >= '0' && char <= '9') ||
(char >= 'a' && char <= 'f') ||
(char >= 'A' && char <= 'F')
}).map(char => {
if char >= '0' && char <= '9' {
char.to_int() - '0'.to_int()
} else if char >= 'a' && char <= 'f' {
char.to_int() - 'a'.to_int() + 10
} else {
char.to_int() - 'A'.to_int() + 10
}
})
}
///|
fn code_unit() -> @parsec.Parser[Char, Int] {
hex_digit()
.count(4)
.map(digits => digits[0] * 4096 + digits[1] * 256 + digits[2] * 16 + digits[3])
}