From 03ff159c952298e49e50dc3bdffbc57d6a5555c4 Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Wed, 19 Oct 2022 22:35:13 -0700 Subject: [PATCH] Use functions not closures --- src/lib.rs | 83 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 35 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f995968..2a64e4a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,17 +41,21 @@ mod tests { Object(HashMap), } - #[test] - fn parse_json() { - let json_null = literal("null").to(JsonValue::Null); - let json_bool = choice(( + trait JsonParser<'a, T>: Parser<&'a str, T, &'a str> {} + impl<'a, T, P> JsonParser<'a, T> for P where P: Parser<&'a str, T, &'a str> {} + + fn json_null<'a>() -> impl JsonParser<'a, JsonValue> { + literal("null").to(JsonValue::Null) + } + fn json_bool<'a>() -> impl JsonParser<'a, JsonValue> { + choice(( literal("true").to(JsonValue::Bool(true)), literal("false").to(JsonValue::Bool(false)), - )); + )) + } + fn json_number() -> impl JsonParser<'static, JsonValue> { let digit = || one_of("1234567890"); - assert_eq!(digit().parse("3"), Ok(("3", ""))); - let digits = || repeated(digit()).at_least(1); let json_number_inner = choice(( @@ -72,40 +76,49 @@ mod tests { )) .map(|digits| digits.parse::().unwrap()); - let json_number = - literal("-") - .optional() - .then(json_number_inner) - .map(|(maybe_sign, mut val)| { - if maybe_sign.is_some() { - val *= -1.0; - } - JsonValue::Num(val) - }); + literal("-") + .optional() + .then(json_number_inner) + .map(|(maybe_sign, mut val)| { + if maybe_sign.is_some() { + val *= -1.0; + } + JsonValue::Num(val) + }) + } - assert_eq!( - json_number.parse("-383").unwrap().0, - JsonValue::Num(-383f64) - ); - assert_eq!( - json_number.parse("-.383").unwrap().0, - JsonValue::Num(-0.383) - ); - assert_eq!(json_number.parse(".383").unwrap().0, JsonValue::Num(0.383)); - assert_eq!( - json_number.parse("-1.383").unwrap().0, - JsonValue::Num(-1.383) - ); - - let json_string = seq(( + fn json_string<'a>() -> impl JsonParser<'a, JsonValue> { + seq(( literal_char('"'), pred(any_char, |ch| *ch != '"'), literal_char('"'), )) - .map(|(_, s, _)| JsonValue::Str(s.to_string())); + .map(|(_, s, _)| JsonValue::Str(s.to_string())) + } - let json_value = choice((json_null, json_bool, json_number, json_string)); + fn json_value() -> impl JsonParser<'static, JsonValue> { + choice((json_null(), json_bool(), json_number(), json_string())) + } - assert_eq!(json_value.parse("true"), Ok((JsonValue::Bool(true), ""))); + #[test] + fn parse_json() { + assert_eq!( + json_number().parse("-383").unwrap().0, + JsonValue::Num(-383f64) + ); + assert_eq!( + json_number().parse("-.383").unwrap().0, + JsonValue::Num(-0.383) + ); + assert_eq!( + json_number().parse(".383").unwrap().0, + JsonValue::Num(0.383) + ); + assert_eq!( + json_number().parse("-1.383").unwrap().0, + JsonValue::Num(-1.383) + ); + + assert_eq!(json_value().parse("true"), Ok((JsonValue::Bool(true), ""))); } }