json numbers

This commit is contained in:
Greg Shuflin 2022-10-17 01:26:33 -07:00
parent 64a50d5bf3
commit 32508b25f5

View File

@ -12,6 +12,7 @@ pub use parser::{ParseResult, Parser};
mod tests { mod tests {
use super::*; use super::*;
use crate::choice::choice; use crate::choice::choice;
use crate::combinators::{one_or_more, zero_or_more};
use crate::primitives::{any_char, literal, literal_char, one_of, pred}; use crate::primitives::{any_char, literal, literal_char, one_of, pred};
use crate::sequence::seq; use crate::sequence::seq;
use std::collections::HashMap; use std::collections::HashMap;
@ -48,8 +49,45 @@ mod tests {
literal("false").to(JsonValue::Bool(false)), literal("false").to(JsonValue::Bool(false)),
)); ));
let digit = one_of("1234567890"); let digit = || one_of("1234567890");
assert_eq!(digit.parse("3"), Ok(("3", ""))); assert_eq!(digit().parse("3"), Ok(("3", "")));
let json_number_inner = choice((
seq((
one_or_more(digit()),
literal(".").then(zero_or_more(digit())).optional(),
))
.map(|(mut digits, maybe_more)| {
if let Some((point, more)) = maybe_more {
digits.push(point);
digits.extend(more.into_iter());
}
digits.into_iter().collect::<String>()
}),
seq((literal("."), one_or_more(digit()))).map(|(_point, digits)| {
let mut d = vec!["."];
d.extend(digits.into_iter());
d.into_iter().collect::<String>()
}),
))
.map(|digits| digits.parse::<f64>().unwrap());
let json_number =
literal("-")
.optional()
.then(json_number_inner)
.map(|(maybe_sign, val)| {
if maybe_sign.is_some() {
val * -1.0
} else {
val
}
});
assert_eq!(json_number.parse("-383").unwrap().0, -383f64);
assert_eq!(json_number.parse("-.383").unwrap().0, -0.383);
assert_eq!(json_number.parse(".383").unwrap().0, 0.383);
assert_eq!(json_number.parse("-1.383").unwrap().0, -1.383);
let json_string = seq(( let json_string = seq((
literal_char('"'), literal_char('"'),