From 74b6a1e410a57e1e8eafebef6e4dad2929fe1622 Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Fri, 21 Oct 2022 18:58:00 -0700 Subject: [PATCH] json object --- src/lib.rs | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d5a9594..3d350d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,7 +15,6 @@ mod tests { use crate::combinators::repeated; use crate::primitives::{any_char, literal, literal_char, one_of, pred}; use crate::sequence::seq; - use std::collections::HashMap; #[test] fn test_parsing() { @@ -38,7 +37,7 @@ mod tests { Str(String), Num(f64), Array(Vec), - Object(HashMap), + Object(Vec<(String, JsonValue)>), } trait JsonParser<'a, T>: Parser<&'a str, T, &'a str> {} @@ -87,13 +86,17 @@ mod tests { }) } - fn json_string() -> impl JsonParser<'static, JsonValue> { + fn json_string_raw() -> impl JsonParser<'static, String> { seq(( literal_char('"'), repeated(pred(any_char, |ch| *ch != '"')), literal_char('"'), )) - .map(|(_, s, _)| JsonValue::Str(s.iter().cloned().collect::())) + .map(|(_, s, _)| s.iter().cloned().collect::()) + } + + fn json_string() -> impl JsonParser<'static, JsonValue> { + json_string_raw().map(JsonValue::Str) } fn whitespace() -> impl JsonParser<'static, ()> { @@ -112,7 +115,20 @@ mod tests { } } - //fn json_object() -> impl JsonParser<'static, JsonValue> {} + fn json_object() -> impl JsonParser<'static, JsonValue> { + move |input| { + let kv = json_string_raw() + .surrounded_by(whitespace()) + .then_ignore(literal_char(':')) + .then(json_value().surrounded_by(whitespace())); + + repeated(kv) + .separated_by(literal_char(','), false) + .delimited(literal_char('{'), literal_char('}')) + .map(JsonValue::Object) + .parse(input) + } + } fn json_value() -> impl JsonParser<'static, JsonValue> { choice(( @@ -121,6 +137,7 @@ mod tests { json_number(), json_string(), json_array(), + json_object(), )) } @@ -168,17 +185,29 @@ mod tests { ) ); assert_eq!( - json_array().parse(r#"[8,null,[],5]"#).unwrap(), + json_array().parse(r#"[8,null,[],5],{}"#).unwrap(), ( JsonValue::Array(vec![ JsonValue::Num(8.), JsonValue::Null, JsonValue::Array(vec![]), - JsonValue::Num(5.) + JsonValue::Num(5.), ]), - "" + ",{}" ) ); assert_eq!(json_value().parse("true"), Ok((JsonValue::Bool(true), ""))); } + + #[test] + fn parse_json() { + assert_eq!( + json_object().parse(r#"{ "a": 23}"#).unwrap().0, + JsonValue::Object(vec![("a".into(), JsonValue::Num(23.))]) + ); + assert_eq!( + json_object().parse(r#"{}"#).unwrap().0, + JsonValue::Object(vec![]) + ); + } }