From 89831df4392ced682ddf5e866f24702a8d67e132 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Fri, 9 Jul 2021 20:48:23 +0800 Subject: [PATCH 1/3] (feat) initial commit of json module --- Cargo.toml | 1 + valuable-json/Cargo.toml | 11 +++++++++++ valuable-json/src/lib.rs | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 valuable-json/Cargo.toml create mode 100644 valuable-json/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 92cffaf..a72d83c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ resolver = "2" members = [ "valuable", "valuable-derive", + "valuable-json", "valuable-serde", "tests", ] diff --git a/valuable-json/Cargo.toml b/valuable-json/Cargo.toml new file mode 100644 index 0000000..14a276d --- /dev/null +++ b/valuable-json/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "valuable-json" +version = "0.1.0" +authors = ["Ning Sun "] +edition = "2018" +license = "MIT" +description = "Valuable instrument for `serde_json::Value`" + +[dependencies] +valuable = { version = "0.1", path = "../valuable", default-features = false } +serde_json = "1" diff --git a/valuable-json/src/lib.rs b/valuable-json/src/lib.rs new file mode 100644 index 0000000..c0d6aec --- /dev/null +++ b/valuable-json/src/lib.rs @@ -0,0 +1,36 @@ +use serde_json::{Value as JsonValue}; +use valuable::{Valuable, Value, Visit}; + +struct Json<'a>(&'a JsonValue); + +impl<'a> Valuable for Json<'a> { + fn as_value(&self) -> Value<'a> { + match self.0 { + // TODO: fixme + JsonValue::Array(ref array) => Value::Listable(array), + JsonValue::Bool(ref value) => Value::Bool(*value), + JsonValue::Number(ref num) => { + // TODO: check correctness for this + if num.is_f64() { + Value::F64(num.as_f64().unwrap()) + } else if num.is_i64() { + Value::I64(num.as_i64().unwrap()) + } else if num.is_u64() { + Value::U64(num.as_u64().unwrap()) + } else { + unreachable!() + } + } + JsonValue::Null => Value::Unit, + JsonValue::String(ref s) => Value::String(s), + JsonValue::Object(ref object) => { + // TODO: make map valuable + Value::Mappable(object), + } + } + } + + fn visit(&self, visit: &mut dyn Visit) { + //TODO: + } +} From 57718dfbd15ad040e58281bd282d4cf8bb2058a9 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Sun, 11 Jul 2021 13:17:38 +0800 Subject: [PATCH 2/3] (feat) impl valuable for json --- Cargo.toml | 1 - valuable-json/Cargo.toml | 11 ------- valuable-json/src/lib.rs | 36 --------------------- valuable/Cargo.toml | 4 +++ valuable/src/json.rs | 68 ++++++++++++++++++++++++++++++++++++++++ valuable/src/lib.rs | 3 ++ 6 files changed, 75 insertions(+), 48 deletions(-) delete mode 100644 valuable-json/Cargo.toml delete mode 100644 valuable-json/src/lib.rs create mode 100644 valuable/src/json.rs diff --git a/Cargo.toml b/Cargo.toml index a72d83c..92cffaf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,6 @@ resolver = "2" members = [ "valuable", "valuable-derive", - "valuable-json", "valuable-serde", "tests", ] diff --git a/valuable-json/Cargo.toml b/valuable-json/Cargo.toml deleted file mode 100644 index 14a276d..0000000 --- a/valuable-json/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "valuable-json" -version = "0.1.0" -authors = ["Ning Sun "] -edition = "2018" -license = "MIT" -description = "Valuable instrument for `serde_json::Value`" - -[dependencies] -valuable = { version = "0.1", path = "../valuable", default-features = false } -serde_json = "1" diff --git a/valuable-json/src/lib.rs b/valuable-json/src/lib.rs deleted file mode 100644 index c0d6aec..0000000 --- a/valuable-json/src/lib.rs +++ /dev/null @@ -1,36 +0,0 @@ -use serde_json::{Value as JsonValue}; -use valuable::{Valuable, Value, Visit}; - -struct Json<'a>(&'a JsonValue); - -impl<'a> Valuable for Json<'a> { - fn as_value(&self) -> Value<'a> { - match self.0 { - // TODO: fixme - JsonValue::Array(ref array) => Value::Listable(array), - JsonValue::Bool(ref value) => Value::Bool(*value), - JsonValue::Number(ref num) => { - // TODO: check correctness for this - if num.is_f64() { - Value::F64(num.as_f64().unwrap()) - } else if num.is_i64() { - Value::I64(num.as_i64().unwrap()) - } else if num.is_u64() { - Value::U64(num.as_u64().unwrap()) - } else { - unreachable!() - } - } - JsonValue::Null => Value::Unit, - JsonValue::String(ref s) => Value::String(s), - JsonValue::Object(ref object) => { - // TODO: make map valuable - Value::Mappable(object), - } - } - } - - fn visit(&self, visit: &mut dyn Visit) { - //TODO: - } -} diff --git a/valuable/Cargo.toml b/valuable/Cargo.toml index 4d7818a..ff4bacd 100644 --- a/valuable/Cargo.toml +++ b/valuable/Cargo.toml @@ -18,8 +18,12 @@ std = ["alloc"] # Provide imps for types in Rust's `alloc` library. alloc = [] +# Provides serde_json::Value instrument for valuable +json = ["serde_json"] + [dependencies] valuable-derive = { version = "0.1.0", optional = true, path = "../valuable-derive" } +serde_json = { version = "1.0.46", optional = true } [dev-dependencies] criterion = "0.3" diff --git a/valuable/src/json.rs b/valuable/src/json.rs new file mode 100644 index 0000000..a106cb6 --- /dev/null +++ b/valuable/src/json.rs @@ -0,0 +1,68 @@ +use serde_json::{Map, Value as Json}; + +use crate::{Mappable, Valuable, Value, Visit}; + +impl Valuable for Json { + fn as_value(&self) -> Value<'_> { + match self { + Json::Array(ref array) => array.as_value(), + Json::Bool(ref value) => value.as_value(), + Json::Number(ref num) => { + // TODO: check correctness for this + if num.is_f64() { + Value::F64(num.as_f64().unwrap()) + } else if num.is_i64() { + Value::I64(num.as_i64().unwrap()) + } else if num.is_u64() { + Value::U64(num.as_u64().unwrap()) + } else { + unreachable!() + } + } + Json::Null => Value::Unit, + Json::String(ref s) => s.as_value(), + Json::Object(ref object) => object.as_value(), + } + } + + fn visit(&self, visit: &mut dyn Visit) { + match self { + Json::Array(ref array) => array.visit(visit), + Json::Bool(ref value) => value.visit(visit), + Json::Number(ref num) => { + // TODO: check correctness for this + if num.is_f64() { + num.as_f64().unwrap().visit(visit) + } else if num.is_i64() { + num.as_i64().unwrap().visit(visit) + } else if num.is_u64() { + num.as_u64().unwrap().visit(visit) + } else { + unreachable!() + } + } + Json::Null => Value::Unit.visit(visit), + Json::String(ref s) => s.visit(visit), + Json::Object(ref object) => object.visit(visit), + } + } +} + +impl Valuable for Map { + fn as_value(&self) -> Value<'_> { + Value::Mappable(self) + } + + fn visit(&self, visit: &mut dyn Visit) { + for (k, v) in self.iter() { + visit.visit_entry(k.as_value(), v.as_value()); + } + } +} + +impl Mappable for Map { + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } +} diff --git a/valuable/src/lib.rs b/valuable/src/lib.rs index 7e61b5a..26c84e0 100644 --- a/valuable/src/lib.rs +++ b/valuable/src/lib.rs @@ -135,3 +135,6 @@ pub use visit::{visit, Visit}; #[cfg(feature = "derive")] pub use valuable_derive::*; + +#[cfg(feature = "json")] +mod json; From 2ccc2bf2e649aa515dda7afd80e6efe63b899a7b Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Mon, 19 Jul 2021 21:26:48 +0800 Subject: [PATCH 3/3] (test) add test for valuable Signed-off-by: Ning Sun --- valuable/src/json.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/valuable/src/json.rs b/valuable/src/json.rs index a106cb6..a451dc0 100644 --- a/valuable/src/json.rs +++ b/valuable/src/json.rs @@ -8,13 +8,10 @@ impl Valuable for Json { Json::Array(ref array) => array.as_value(), Json::Bool(ref value) => value.as_value(), Json::Number(ref num) => { - // TODO: check correctness for this if num.is_f64() { Value::F64(num.as_f64().unwrap()) } else if num.is_i64() { Value::I64(num.as_i64().unwrap()) - } else if num.is_u64() { - Value::U64(num.as_u64().unwrap()) } else { unreachable!() } @@ -30,13 +27,10 @@ impl Valuable for Json { Json::Array(ref array) => array.visit(visit), Json::Bool(ref value) => value.visit(visit), Json::Number(ref num) => { - // TODO: check correctness for this if num.is_f64() { num.as_f64().unwrap().visit(visit) } else if num.is_i64() { num.as_i64().unwrap().visit(visit) - } else if num.is_u64() { - num.as_u64().unwrap().visit(visit) } else { unreachable!() } @@ -66,3 +60,19 @@ impl Mappable for Map { (len, Some(len)) } } + +#[cfg(test)] +mod test { + use crate::{Valuable, Value}; + use serde_json::json; + + #[test] + fn test_json() { + let j = json!({"a": 100, "b": 1.0, "c": -1}); + let jv = j.as_value(); + + assert!(matches!(jv, Value::Mappable(_))); + + assert!(matches!(json!(100).as_value(), Value::I64(_))); + } +}