From 5b653ab8a00414bb26f8e3b074901894bf6397ac Mon Sep 17 00:00:00 2001 From: freestrings Date: Wed, 15 May 2019 18:19:00 +0900 Subject: [PATCH] REAEME.md - Selector's "map" --- README.md | 58 ++++++++--- src/select/mod.rs | 47 +++++++-- tests/readme.rs | 247 ++++++++++++++++++++++++++++++++++++++++++++++ tests/selector.rs | 30 +++--- wasm/README.md | 2 +- wasm/src/lib.rs | 3 +- 6 files changed, 347 insertions(+), 40 deletions(-) create mode 100644 tests/readme.rs diff --git a/README.md b/README.md index 5105fac..0ad07c3 100644 --- a/README.md +++ b/README.md @@ -75,16 +75,41 @@ let result = selector .path("$..[?(@.age >= 30)]").unwrap() // .value_from_str(&serde_json::to_string(&json_obj).unwrap() /*&str*/).unwrap() // .value_from(&json_obj /*&impl serde::ser::Serialize*/).unwrap() - .value(&json_obj /*serde_json::value::Value*/ ).unwrap() - .select_to_value().unwrap(); + .value(&json_obj /*serde_json::value::Value*/).unwrap() + .select_as_value().unwrap(); assert_eq!(json!([{"name": "친구3", "age": 30}]), result); -let result = selector.select_to_str().unwrap(); +let result = selector.select_as_str().unwrap(); assert_eq!(r#"[{"name":"친구3","age":30}]"#, result); -let result = selector.select_to::>().unwrap(); +let result = selector.select_as::>().unwrap(); assert_eq!(vec![Friend { name: "친구3".to_string(), age: Some(30) }], result); + +let _ = selector.map(|v| { + let r = match v { + Value::Array(mut vec) => { + for mut v in &mut vec { + v.as_object_mut().unwrap().remove("age"); + } + Value::Array(vec) + } + _ => Value::Null + }; + Some(r) +}); +assert_eq!(json!([{ "name": "친구3" }]), selector.get().unwrap()); + +let _ = selector.value(&json_obj).unwrap() + .map_as(|mut v: Vec| { + let mut f = v.pop().unwrap(); + f.name = "friend3".to_string(); + f.age = None; + Some(vec![f]) + }); + +assert_eq!(vec![Friend { name: "friend3".to_string(), age: None }], + selector.get_as::>().unwrap()); ``` #### Rust - jsonpath::select(json: &serde_json::value::Value, jsonpath: &str) @@ -322,15 +347,22 @@ let selector = new jsonpath.Selector(); selector.path('$..friends[0]'); selector.value(jsonObj); -let selectToObj = selector.selectTo(); -let selectToString = selector.selectToStr(); +let selectAsObj = selector.selectAs(); +let selectAsString = selector.selectAsStr(); console.log( - JSON.stringify(ret) == JSON.stringify(selectToObj), - JSON.stringify(ret) == selectToString + JSON.stringify(ret) == JSON.stringify(selectAsObj), + JSON.stringify(ret) == selectAsString ); -// => true, true +selector.map(function(v) { + let f1 = v[0]; + f1.name = 'friend3'; + return [f1]; +}); + +console.log(JSON.stringify(selector.get()) === JSON.stringify([{"name": "friend3", "age": 30}])); +// => true ``` ##### jsonpath-rs @@ -358,12 +390,12 @@ let selector = new jsonpath.Selector() .path('$..friends[0]') .value(jsonObj); -let selectToObj = selector.selectTo(); -let selectToString = selector.selectToStr(); +let selectAsObj = selector.selectAs(); +let selectAsString = selector.selectAsStr(); console.log( - JSON.stringify(ret) == JSON.stringify(selectToObj), - JSON.stringify(ret) == selectToString + JSON.stringify(ret) == JSON.stringify(selectAsObj), + JSON.stringify(ret) == selectAsString ); // => true, true diff --git a/src/select/mod.rs b/src/select/mod.rs index 10403fb..66fd576 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -22,7 +22,7 @@ use super::ref_value::model::*; /// #[derive(Serialize, Deserialize, PartialEq, Debug)] /// struct Person { /// name: String, -/// age: u8, +/// age: Option, /// phone: String, /// } /// @@ -55,25 +55,52 @@ use super::ref_value::model::*; /// let result = selector /// .path("$..[?(@.age > 40)]").unwrap() /// .value_from_str(input_str()).unwrap() -/// .select_to_value().unwrap(); +/// .select_as_value().unwrap(); /// assert_eq!(input_json()[1], result[0]); /// -/// let result = selector.select_to_str().unwrap(); +/// let result = selector.select_as_str().unwrap(); /// assert_eq!(serde_json::to_string(&vec![&input_json()[1].clone()]).unwrap(), result); /// -/// let result = selector.select_to::>().unwrap(); +/// let result = selector.select_as::>().unwrap(); /// assert_eq!(input_person()[1], result[0]); /// /// let _ = selector.path("$..[?(@.age == 40)]"); /// -/// let result = selector.select_to_value().unwrap(); +/// let result = selector.select_as_value().unwrap(); /// assert_eq!(input_json()[0], result[0]); /// -/// let result = selector.select_to_str().unwrap(); +/// let result = selector.select_as_str().unwrap(); /// assert_eq!(serde_json::to_string(&vec![&input_json()[0].clone()]).unwrap(), result); /// -/// let result = selector.select_to::>().unwrap(); +/// let result = selector.select_as::>().unwrap(); /// assert_eq!(input_person()[0], result[0]); +/// +/// selector.map(|v| { +/// let r = match v { +/// Value::Array(mut vec) => { +/// for mut v in &mut vec { +/// v.as_object_mut().unwrap().remove("age"); +/// } +/// Value::Array(vec) +/// } +/// _ => Value::Null +/// }; +/// Some(r) +/// }); +/// assert_eq!( +/// serde_json::from_str::(r#"[{ "name": "이름1", "phone": "+33 12341234"}]"#).unwrap(), +/// selector.get().unwrap()); +/// +/// selector.value_from_str(input_str()).unwrap() +/// .map_as(|mut v: Vec| { +/// let mut p = v.pop().unwrap(); +/// p.name = "name1".to_string(); +/// p.age = None; +/// Some(vec![p]) +/// }); +/// assert_eq!( +/// vec![Person { name: "name1".to_string(), age: None, phone: "+33 12341234".to_string() }], +/// selector.get_as::>().unwrap()); /// ``` #[derive(Debug)] pub struct Selector { @@ -182,10 +209,10 @@ impl Selector { Ok(self) } - pub fn get(&self) -> Value { + pub fn get(&self) -> result::Result { match &self.value { - Some(value) => value.into(), - _ => Value::Null + Some(value) => Ok(value.into()), + _ => Err(SelectorErrorMessage::EmptyValue.to_string()) } } diff --git a/tests/readme.rs b/tests/readme.rs new file mode 100644 index 0000000..459a736 --- /dev/null +++ b/tests/readme.rs @@ -0,0 +1,247 @@ +extern crate jsonpath_lib as jsonpath; +extern crate serde; +#[macro_use] +extern crate serde_json; + +use serde::{Deserialize, Serialize}; +use serde_json::Value; + +use jsonpath::Selector; + +#[test] +fn readme_selector() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Friend { + name: String, + age: Option, + } + + let json_obj = json!({ + "school": { + "friends": [ + {"name": "친구1", "age": 20}, + {"name": "친구2", "age": 20} + ] + }, + "friends": [ + {"name": "친구3", "age": 30}, + {"name": "친구4"} + ]}); + + let mut selector = Selector::new(); + + let result = selector + .path("$..[?(@.age >= 30)]").unwrap() +// .value_from_str(&serde_json::to_string(&json_obj).unwrap() /*&str*/).unwrap() +// .value_from(&json_obj /*&impl serde::ser::Serialize*/).unwrap() + .value(&json_obj /*serde_json::value::Value*/).unwrap() + .select_as_value().unwrap(); + + assert_eq!(json!([{"name": "친구3", "age": 30}]), result); + + let result = selector.select_as_str().unwrap(); + assert_eq!(r#"[{"name":"친구3","age":30}]"#, result); + + let result = selector.select_as::>().unwrap(); + assert_eq!(vec![Friend { name: "친구3".to_string(), age: Some(30) }], result); + + let _ = selector.map(|v| { + let r = match v { + Value::Array(mut vec) => { + for mut v in &mut vec { + v.as_object_mut().unwrap().remove("age"); + } + Value::Array(vec) + } + _ => Value::Null + }; + Some(r) + }); + assert_eq!(json!([{ "name": "친구3"}]), selector.get().unwrap()); + + let _ = selector.value(&json_obj).unwrap() + .map_as(|mut v: Vec| { + let mut f = v.pop().unwrap(); + f.name = "friend3".to_string(); + f.age = None; + Some(vec![f]) + }); + assert_eq!(vec![Friend { name: "friend3".to_string(), age: None }], + selector.get_as::>().unwrap()); +} + +#[test] +fn readme_select() { + let json_obj = json!({ + "school": { + "friends": [ + {"name": "친구1", "age": 20}, + {"name": "친구2", "age": 20} + ] + }, + "friends": [ + {"name": "친구3", "age": 30}, + {"name": "친구4"} + ]}); + + let json = jsonpath::select(&json_obj, "$..friends[0]").unwrap(); + + let ret = json!([ + {"name": "친구3", "age": 30}, + {"name": "친구1", "age": 20} + ]); + assert_eq!(json, ret); +} + +#[test] +fn readme_select_as_str() { + let ret = jsonpath::select_as_str(r#" + { + "school": { + "friends": [ + {"name": "친구1", "age": 20}, + {"name": "친구2", "age": 20} + ] + }, + "friends": [ + {"name": "친구3", "age": 30}, + {"name": "친구4"} + ] + } + "#, "$..friends[0]").unwrap(); + + assert_eq!(ret, r#"[{"name":"친구3","age":30},{"name":"친구1","age":20}]"#); +} + +#[test] +fn readme_select_as() { + #[derive(Deserialize, PartialEq, Debug)] + struct Person { + name: String, + age: u8, + phones: Vec, + } + + let ret: Person = jsonpath::select_as(r#" + { + "person": + { + "name": "Doe John", + "age": 44, + "phones": [ + "+44 1234567", + "+44 2345678" + ] + } + } + "#, "$.person").unwrap(); + + let person = Person { + name: "Doe John".to_string(), + age: 44, + phones: vec!["+44 1234567".to_string(), "+44 2345678".to_string()], + }; + + assert_eq!(person, ret); +} + +#[test] +fn readme_compile() { + let mut template = jsonpath::compile("$..friends[0]"); + + let json_obj = json!({ + "school": { + "friends": [ + {"name": "친구1", "age": 20}, + {"name": "친구2", "age": 20} + ] + }, + "friends": [ + {"name": "친구3", "age": 30}, + {"name": "친구4"} + ]}); + + let json = template(&json_obj).unwrap(); + + let ret = json!([ + {"name": "친구3", "age": 30}, + {"name": "친구1", "age": 20} + ]); + + assert_eq!(json, ret); +} + +#[test] +fn readme_selector_fn() { + let json_obj = json!({ + "school": { + "friends": [ + {"name": "친구1", "age": 20}, + {"name": "친구2", "age": 20} + ] + }, + "friends": [ + {"name": "친구3", "age": 30}, + {"name": "친구4"} + ]}); + + let mut selector = jsonpath::selector(&json_obj); + + let json = selector("$..friends[0]").unwrap(); + + let ret = json!([ + {"name": "친구3", "age": 30}, + {"name": "친구1", "age": 20} + ]); + + assert_eq!(json, ret); + + let json = selector("$..friends[1]").unwrap(); + + let ret = json!([ + {"name": "친구4"}, + {"name": "친구2", "age": 20} + ]); + + assert_eq!(json, ret); +} + +#[test] +fn readme_selector_as() { + let json_obj = json!({ + "school": { + "friends": [ + {"name": "친구1", "age": 20}, + {"name": "친구2", "age": 20} + ] + }, + "friends": [ + {"name": "친구3", "age": 30}, + {"name": "친구4"} + ]}); + + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Friend { + name: String, + age: Option, + } + + let mut selector = jsonpath::selector_as::>(&json_obj); + + let json = selector("$..friends[0]").unwrap(); + + let ret = vec!( + Friend { name: "친구3".to_string(), age: Some(30) }, + Friend { name: "친구1".to_string(), age: Some(20) } + ); + assert_eq!(json, ret); + + let json = selector("$..friends[1]").unwrap(); + + let ret = vec!( + Friend { name: "친구4".to_string(), age: None }, + Friend { name: "친구2".to_string(), age: Some(20) } + ); + + assert_eq!(json, ret); +} \ No newline at end of file diff --git a/tests/selector.rs b/tests/selector.rs index e86594e..19dc07f 100644 --- a/tests/selector.rs +++ b/tests/selector.rs @@ -53,7 +53,7 @@ fn selector_value_from() { let result = Selector::new() .path("$..[?(@.age > 40)]").unwrap() .value_from(&input_person()).unwrap() - .select_to::>().unwrap(); + .select_as::>().unwrap(); assert_eq!(input_person()[1], result[0]); } @@ -62,7 +62,7 @@ fn selector_value() { let result = Selector::new() .path("$..[?(@.age > 40)]").unwrap() .value((&input_json()).into()).unwrap() - .select_to_value().unwrap(); + .select_as_value().unwrap(); assert_eq!(input_json()[1], result[0]); } @@ -71,7 +71,7 @@ fn selector_value_from_str() { let result = Selector::new() .path("$..[?(@.age > 40)]").unwrap() .value_from_str(input_str()).unwrap() - .select_to_value().unwrap(); + .select_as_value().unwrap(); assert_eq!(input_json()[1], result[0]); } @@ -82,25 +82,25 @@ fn selector_select_to() { let result = selector .path("$..[?(@.age > 40)]").unwrap() .value_from_str(input_str()).unwrap() - .select_to_value().unwrap(); + .select_as_value().unwrap(); assert_eq!(input_json()[1], result[0]); - let result = selector.select_to_str().unwrap(); + let result = selector.select_as_str().unwrap(); let value: Value = serde_json::from_str(&result).unwrap(); assert_eq!(input_json()[1], value[0]); - let result = selector.select_to::>().unwrap(); + let result = selector.select_as::>().unwrap(); assert_eq!(input_person()[1], result[0]); let _ = selector.path("$..[?(@.age == 40)]"); - let result = selector.select_to_value().unwrap(); + let result = selector.select_as_value().unwrap(); assert_eq!(input_json()[0], result[0]); - let result = selector.select_to_str().unwrap(); + let result = selector.select_as_str().unwrap(); assert_eq!(serde_json::to_string(&vec![&input_json()[0].clone()]).unwrap(), result); - let result = selector.select_to::>().unwrap(); + let result = selector.select_as::>().unwrap(); assert_eq!(input_person()[0], result[0]); } @@ -145,7 +145,7 @@ fn selector_map_basic() { .path("$..[?(@.age > 40)]").unwrap() .value_from_str(input_str()).unwrap() .map(_remove_name).unwrap() - .get(); + .get().unwrap(); assert_eq!(result, json!([ {"phone": "++44 12341234", "age": 42}, @@ -155,7 +155,7 @@ fn selector_map_basic() { } #[test] -fn selector_map_chain() { +fn selector_map() { let mut selector = Selector::new(); let result = selector @@ -164,7 +164,7 @@ fn selector_map_chain() { .map(_remove_name).unwrap() .path("$..[?(@.age == 50)]").unwrap() .map(_change_phone_number).unwrap() - .get(); + .get().unwrap(); assert_eq!(result, json!({ "phone": "1234", @@ -180,7 +180,7 @@ fn selector_map_as_basic() { .path("$..[?(@.age > 40)]").unwrap() .value_from_str(input_str()).unwrap() .map_as(_rejuvenate).unwrap() - .get(); + .get().unwrap(); assert_eq!(result, json!([ {"name": "이름2", "phone": "++44 12341234", "age": 32}, @@ -190,7 +190,7 @@ fn selector_map_as_basic() { } #[test] -fn selector_map_as_chain() { +fn selector_map_as() { let mut selector = Selector::new(); let result = selector @@ -199,7 +199,7 @@ fn selector_map_as_chain() { .map_as(_rejuvenate).unwrap() .path("$..[?(@.age == 40)]").unwrap() .map(_change_phone_number).unwrap() - .get(); + .get().unwrap(); assert_eq!(result, json!({ "name": "이름3", diff --git a/wasm/README.md b/wasm/README.md index d43f20c..d700c8e 100644 --- a/wasm/README.md +++ b/wasm/README.md @@ -14,7 +14,7 @@ It is Webassembly version of [jsonpath_lib](https://github.com/freestrings/jsonp ### jsonpath.Selector -> Selector's selectTo function is deprecated. since 0.1.3 +> The selectTo function is deprecated since 0.1.3. please use the selectAs function instead. ```javascript let jsonpath = require('jsonpath-wasm'); diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs index 6b7522b..a495d24 100644 --- a/wasm/src/lib.rs +++ b/wasm/src/lib.rs @@ -267,7 +267,8 @@ impl Selector { #[wasm_bindgen(catch)] pub fn get(&mut self) -> result::Result { - JsValue::from_serde(&self.selector.get()).map_err(|e| JsValue::from_str(&e.to_string())) + let v = self.selector.get().map_err(|e| JsValue::from_str(&e.to_string()))?; + JsValue::from_serde(&v).map_err(|e| JsValue::from_str(&e.to_string())) } }