jsonpath-wasm add "map", "get" function

This commit is contained in:
freestrings 2019-05-15 16:10:14 +09:00
parent 135d3c319b
commit 9d8ab7ae23
4 changed files with 98 additions and 9 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "jsonpath-wasm" name = "jsonpath-wasm"
version = "0.1.2" version = "0.1.3"
authors = ["Changseok Han <freestrings@gmail.com>"] authors = ["Changseok Han <freestrings@gmail.com>"]
description = "It is Webassembly version of jsonpath_lib that is JsonPath engine written in Rust - Demo: https://freestrings.github.io/jsonpath" description = "It is Webassembly version of jsonpath_lib that is JsonPath engine written in Rust - Demo: https://freestrings.github.io/jsonpath"
keywords = ["jsonpath", "json", "webassembly", "parsing", "rust"] keywords = ["jsonpath", "json", "webassembly", "parsing", "rust"]
@ -24,12 +24,12 @@ serde = "1.0"
serde_json = { version = "1.0", features = ["preserve_order"] } serde_json = { version = "1.0", features = ["preserve_order"] }
lazy_static = "1.3.0" lazy_static = "1.3.0"
web-sys = { version = "0.3", features = ['console'] } web-sys = { version = "0.3", features = ['console'] }
js-sys = "0.3"
[dev-dependencies] [dev-dependencies]
wasm-bindgen-test = "0.2" wasm-bindgen-test = "0.2"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
js-sys = "0.3"
[profile.release] [profile.release]
opt-level = "s" opt-level = "s"

View File

@ -14,9 +14,11 @@ It is Webassembly version of [jsonpath_lib](https://github.com/freestrings/jsonp
### jsonpath.Selector ### jsonpath.Selector
> Selector's selectTo function is deprecated since 0.1.3 > Selector's selectTo function is deprecated. since 0.1.3
```javascript ```javascript
let jsonpath = require('jsonpath-wasm');
let jsonObj = { let jsonObj = {
"school": { "school": {
"friends": [ "friends": [
@ -30,25 +32,45 @@ let jsonObj = {
] ]
}; };
let selector = new jsonpath.Selector().value(jsonObj); let selector = new jsonpath.Selector();
selector.value(jsonObj);
{ {
let jsonObj = selector.path('$..[?(@.age >= 30)]').selectAs(); selector.path('$..[?(@.age >= 30)]');
let jsonObj = selector.selectAs();
let resultObj = [{"name": "친구3", "age": 30}]; let resultObj = [{"name": "친구3", "age": 30}];
console.log(JSON.stringify(jsonObj) === JSON.stringify(resultObj)); console.log(JSON.stringify(jsonObj) === JSON.stringify(resultObj));
} }
{ {
let jsonObj = selector.path('$..[?(@.age == 20)]').selectAs(); selector.path('$..[?(@.age == 20)]');
let jsonObj = selector.selectAs();
let resultObj = [{"name": "친구1", "age": 20}, {"name": "친구2", "age": 20}]; let resultObj = [{"name": "친구1", "age": 20}, {"name": "친구2", "age": 20}];
console.log(JSON.stringify(jsonObj) === JSON.stringify(resultObj)); console.log(JSON.stringify(jsonObj) === JSON.stringify(resultObj));
} }
{ {
let jsonObj = selector.value({"friends": [ {"name": "친구5", "age": 20} ]}).selectAs(); selector.value({"friends": [ {"name": "친구5", "age": 20} ]});
let jsonObj = selector.selectAs();
let resultObj = [{"name": "친구5", "age": 20}]; let resultObj = [{"name": "친구5", "age": 20}];
console.log(JSON.stringify(jsonObj) === JSON.stringify(resultObj)); console.log(JSON.stringify(jsonObj) === JSON.stringify(resultObj));
} }
{
selector.value(jsonObj);
selector.map(function(v) {
let f1 = v[0];
f1.age = 30;
return v;
});
let resultObj1 = [{"name": "친구1", "age": 30}, {"name": "친구2", "age": 20}];
console.log(JSON.stringify(selector.get()) === JSON.stringify(resultObj1));
selector.path('$..[?(@.age == 20)]');
let jsonObj1 = selector.selectAs();
let resultObj2 = [{"name": "친구2", "age": 20}];
console.log(JSON.stringify(jsonObj1) === JSON.stringify(resultObj2));
}
``` ```
### jsonpath.select(json: string|object, jsonpath: string) ### jsonpath.select(json: string|object, jsonpath: string)

View File

@ -1,4 +1,5 @@
extern crate cfg_if; extern crate cfg_if;
extern crate js_sys;
extern crate jsonpath_lib as jsonpath; extern crate jsonpath_lib as jsonpath;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
@ -18,6 +19,8 @@ use jsonpath::filter::value_filter::JsonValueFilter;
use jsonpath::parser::parser::{Node, NodeVisitor, Parser}; use jsonpath::parser::parser::{Node, NodeVisitor, Parser};
use jsonpath::ref_value::model::{RefValue, RefValueWrapper}; use jsonpath::ref_value::model::{RefValue, RefValueWrapper};
use jsonpath::Selector as _Selector; use jsonpath::Selector as _Selector;
use serde_json::Value;
use wasm_bindgen::*;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use web_sys::console; use web_sys::console;
@ -106,7 +109,7 @@ pub extern fn alloc_json(js_value: JsValue) -> usize {
*idx *idx
} }
Err(e) => { Err(e) => {
console::log_1(&e.into()); console::error_1(&e.into());
0 0
} }
} }
@ -222,7 +225,49 @@ impl Selector {
let ref_value = self.selector.select_as::<RefValue>() let ref_value = self.selector.select_as::<RefValue>()
.map_err(|e| JsValue::from_str(&e))?; .map_err(|e| JsValue::from_str(&e))?;
Ok(JsValue::from_serde(&ref_value) Ok(JsValue::from_serde(&ref_value)
.map_err(|e| JsValue::from_str(&format!("{:?}", e)))?) .map_err(|e| JsValue::from_str(&e.to_string()))?)
}
#[wasm_bindgen(catch)]
pub fn map(&mut self, func: JsValue) -> result::Result<(), JsValue> {
if !func.is_function() {
return Err(JsValue::from_str("Not a function argument"));
}
let cb: &js_sys::Function = JsCast::unchecked_ref(func.as_ref());
self.selector.map(|v| {
let str_value = match JsValue::from_serde(&v) {
Ok(str_value) => str_value,
Err(e) => return {
console::error_1(&JsValue::from_str(&e.to_string()));
None
}
};
match cb.call1(&func, &str_value) {
Ok(ret) => {
match into_serde_json::<Value>(&ret) {
Ok(value) => Some(value),
Err(e) => {
console::error_1(&JsValue::from_str(&e.to_string()));
None
}
}
}
Err(e) => {
console::error_1(&e);
None
}
}
}).map_err(|e| JsValue::from_str(&e))?;
Ok(())
}
#[wasm_bindgen(catch)]
pub fn get(&mut self) -> result::Result<JsValue, JsValue> {
JsValue::from_serde(&self.selector.get()).map_err(|e| JsValue::from_str(&e.to_string()))
} }
} }

View File

@ -10,6 +10,7 @@ extern crate wasm_bindgen_test;
use serde_json::Value; use serde_json::Value;
use wasm_bindgen::*; use wasm_bindgen::*;
use wasm_bindgen::prelude::*;
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
wasm_bindgen_test_configure!(run_in_browser); wasm_bindgen_test_configure!(run_in_browser);
@ -113,6 +114,27 @@ fn selector_struct() {
let mut selector = jsonpath::Selector::new(); let mut selector = jsonpath::Selector::new();
selector.path("$..book[2]").unwrap(); selector.path("$..book[2]").unwrap();
selector.value(JsValue::from_str(json_str())).unwrap(); selector.value(JsValue::from_str(json_str())).unwrap();
let json: Value = selector.select_as().unwrap().into_serde().unwrap(); let json: Value = selector.select_as().unwrap().into_serde().unwrap();
assert_eq!(json, target_json()); assert_eq!(json, target_json());
let cb = Closure::wrap(Box::new(|js_value: JsValue| {
match js_value.into_serde().unwrap() {
Value::Array(mut vec) => {
match vec.pop().unwrap() {
Value::Object(mut map) => {
map.clear();
map.insert("key".to_string(), Value::String("value".to_string()));
JsValue::from_serde(&Value::Object(map)).unwrap()
}
_ => return JsValue::NULL
}
}
_ => return JsValue::NULL
}
}) as Box<Fn(JsValue) -> JsValue>);
selector.map(cb.as_ref().clone()).unwrap();
let js_value = selector.get().unwrap();
assert_eq!(js_value.into_serde::<Value>().unwrap(), json!({ "key": "value" }));
} }