///|
fn digit() -> @parsec.Parser[Char, Char] {
@parsec.Parser::satisfy("digit", char => char >= '0' && char <= '9')
}
///|
fn digits() -> @parsec.Parser[Char, String] {
digit().many1().map(chars => String::from_array(chars[:]))
}
///|
fn integer_part() -> @parsec.Parser[Char, String] {
raw_char('0', expected="JSON integer")
.replace("0")
.or_else(
@parsec.Parser::satisfy("non-zero JSON digit", char => {
char >= '1' && char <= '9'
})
.then(digit().many())
.map(pair => {
let chars = [pair.0]
for char in pair.1 {
chars.push(char)
}
String::from_array(chars[:])
}),
)
}
///|
fn number() -> @parsec.Parser[Char, String] {
let sign = raw_char('-', expected="JSON number").replace("-").option("")
let fraction = raw_char('.', expected="fraction")
.then_right(digits())
.map(value => join([".", value]))
.option("")
let exponent_marker = raw_char('e', expected="exponent")
.or_else(raw_char('E', expected="exponent"))
.map(character => String::from_array([character]))
let exponent = exponent_marker
.then(
raw_char('+', expected="exponent sign")
.replace("+")
.or_else(raw_char('-', expected="exponent sign").replace("-"))
.option("")
.then(digits()),
)
.map(pair => join([pair.0, pair.1.0, pair.1.1]))
.option("")
sign
.then(integer_part())
.then(fraction)
.then(exponent)
.map(parts => join([parts.0.0.0, parts.0.0.1, parts.0.1, parts.1]))
.then_left(json_whitespace())
}