From 282398c7b138068ffac0d75e85596c638581673c Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Thu, 20 Oct 2022 18:10:13 -0700 Subject: [PATCH] Fix string bug; delimited --- src/lib.rs | 31 ++++++++++++++++++++++++------- src/parser.rs | 14 ++++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 277e323..50f76b3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -87,13 +87,13 @@ mod tests { }) } - fn json_string<'a>() -> impl JsonParser<'a, JsonValue> { + fn json_string() -> impl JsonParser<'static, JsonValue> { seq(( literal_char('"'), - pred(any_char, |ch| *ch != '"'), + repeated(pred(any_char, |ch| *ch != '"')), literal_char('"'), )) - .map(|(_, s, _)| JsonValue::Str(s.to_string())) + .map(|(_, s, _)| JsonValue::Str(s.iter().cloned().collect::())) } fn whitespace() -> impl JsonParser<'static, ()> { @@ -101,11 +101,12 @@ mod tests { } fn json_array() -> impl JsonParser<'static, JsonValue> { - let val = whitespace().ignore_then(json_value()).then_ignore(whitespace()); + let val = whitespace() + .ignore_then(json_value()) + .then_ignore(whitespace()); - literal_char('[') - .ignore_then(repeated(val)) - .then_ignore(literal_char(']')) + repeated(val) + .delimited(literal_char('['), literal_char(']')) .map(JsonValue::Array) } @@ -115,6 +116,22 @@ mod tests { #[test] fn parse_json() { + assert_eq!( + json_string().parse(r#""yolo swagg""#).unwrap(), + (JsonValue::Str("yolo swagg".into()), "") + ); + //TODO not correct! + assert_eq!( + json_array().parse(r#"[ 4 9 "foo" ]"#).unwrap(), + ( + JsonValue::Array(vec![ + JsonValue::Num(4.), + JsonValue::Num(9.0), + JsonValue::Str("foo".to_string()) + ]), + "" + ) + ); assert_eq!( json_number().parse("-383").unwrap().0, JsonValue::Num(-383f64) diff --git a/src/parser.rs b/src/parser.rs index cf42593..c68fda0 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -70,6 +70,20 @@ pub trait Parser { .map(|(this_output, _)| this_output) } + fn delimited<'a, P1, O1, P2, O2>(self, left: P1, right: P2) -> BoxedParser<'a, I, O, E> + where + Self: Sized + 'a, + I: 'a, + O1: 'a, + O2: 'a, + O: 'a, + E: 'a, + P1: Parser + 'a, + P2: Parser + 'a, + { + crate::sequence::seq((left, self, right)).map(|(_, output, _)| output) + } + fn optional<'a>(self) -> BoxedParser<'a, I, Option, E> where I: Clone + 'a,