More JSON

This commit is contained in:
Greg Shuflin 2022-10-16 21:36:23 -07:00
parent 2dc754c294
commit dd9c05ccd1
2 changed files with 21 additions and 4 deletions

View File

@ -12,7 +12,8 @@ pub use parser::{ParseResult, Parser};
mod tests { mod tests {
use super::*; use super::*;
use crate::choice::choice; use crate::choice::choice;
use crate::primitives::literal; use crate::primitives::{any_char, literal, literal_char, pred};
use crate::sequence::seq;
use std::collections::HashMap; use std::collections::HashMap;
#[test] #[test]
@ -42,10 +43,19 @@ mod tests {
#[test] #[test]
fn parse_json() { fn parse_json() {
let json_null = literal("null").to(JsonValue::Null); let json_null = literal("null").to(JsonValue::Null);
let json_true = literal("true").to(JsonValue::Bool(true)); let json_bool = choice((
let json_false = literal("false").to(JsonValue::Bool(false)); literal("true").to(JsonValue::Bool(true)),
literal("false").to(JsonValue::Bool(false)),
));
let json_value = choice((json_null, json_true, json_false)); let json_string = seq((
literal_char('"'),
pred(any_char, |ch| *ch != '"'),
literal_char('"'),
))
.map(|(_, s, _)| JsonValue::Str(s.to_string()));
let json_value = choice((json_null, json_bool, json_string));
assert_eq!(json_value.parse("true"), Ok((JsonValue::Bool(true), ""))); assert_eq!(json_value.parse("true"), Ok((JsonValue::Bool(true), "")));
} }

View File

@ -1,5 +1,12 @@
use crate::parser::{ParseResult, Parser}; use crate::parser::{ParseResult, Parser};
pub fn literal_char(expected: char) -> impl Fn(&str) -> ParseResult<&str, char, &str> {
move |input| match input.chars().next() {
Some(ch) if ch == expected => Ok((expected, &input[ch.len_utf8()..])),
_ => Err(input),
}
}
pub fn literal(expected: &'static str) -> impl Fn(&str) -> ParseResult<&str, &str, &str> { pub fn literal(expected: &'static str) -> impl Fn(&str) -> ParseResult<&str, &str, &str> {
move |input| match input.get(0..expected.len()) { move |input| match input.get(0..expected.len()) {
Some(next) if next == expected => Ok((expected, &input[expected.len()..])), Some(next) if next == expected => Ok((expected, &input[expected.len()..])),