Fix string bug; delimited

This commit is contained in:
Greg Shuflin 2022-10-20 18:10:13 -07:00
parent e279fe314f
commit 282398c7b1
2 changed files with 38 additions and 7 deletions

View File

@ -87,13 +87,13 @@ mod tests {
}) })
} }
fn json_string<'a>() -> impl JsonParser<'a, JsonValue> { fn json_string() -> impl JsonParser<'static, JsonValue> {
seq(( seq((
literal_char('"'), literal_char('"'),
pred(any_char, |ch| *ch != '"'), repeated(pred(any_char, |ch| *ch != '"')),
literal_char('"'), literal_char('"'),
)) ))
.map(|(_, s, _)| JsonValue::Str(s.to_string())) .map(|(_, s, _)| JsonValue::Str(s.iter().cloned().collect::<String>()))
} }
fn whitespace() -> impl JsonParser<'static, ()> { fn whitespace() -> impl JsonParser<'static, ()> {
@ -101,11 +101,12 @@ mod tests {
} }
fn json_array() -> impl JsonParser<'static, JsonValue> { 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('[') repeated(val)
.ignore_then(repeated(val)) .delimited(literal_char('['), literal_char(']'))
.then_ignore(literal_char(']'))
.map(JsonValue::Array) .map(JsonValue::Array)
} }
@ -115,6 +116,22 @@ mod tests {
#[test] #[test]
fn parse_json() { 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!( assert_eq!(
json_number().parse("-383").unwrap().0, json_number().parse("-383").unwrap().0,
JsonValue::Num(-383f64) JsonValue::Num(-383f64)

View File

@ -70,6 +70,20 @@ pub trait Parser<I, O, E> {
.map(|(this_output, _)| this_output) .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<I, O1, E> + 'a,
P2: Parser<I, O2, E> + 'a,
{
crate::sequence::seq((left, self, right)).map(|(_, output, _)| output)
}
fn optional<'a>(self) -> BoxedParser<'a, I, Option<O>, E> fn optional<'a>(self) -> BoxedParser<'a, I, Option<O>, E>
where where
I: Clone + 'a, I: Clone + 'a,