RefValue serde 구현. bump up version. 0.1.5

This commit is contained in:
freestrings 2019-03-18 10:59:08 +09:00
parent 482c957003
commit b24a8c18a9
33 changed files with 949 additions and 629 deletions

12
.idea/runConfigurations/serde.xml generated Normal file
View File

@ -0,0 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="serde" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package jsonpath_lib --test serde &quot;&quot;" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="SHORT" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@ -1,6 +1,6 @@
[package]
name = "jsonpath_lib"
version = "0.1.4"
version = "0.1.5"
authors = ["Changseok Han <freestrings@gmail.com>"]
description = "JsonPath in Rust and Webassembly - Webassembly Demo: https://freestrings.github.io/jsonpath"

View File

@ -29,6 +29,7 @@ To enjoy Rust!
- [jsonpath_lib library](#jsonpath_lib-library)
- [rust - jsonpath::select(json: &serde_json::value::Value, jsonpath: &str)](#rust---jsonpathselectjson-serde_jsonvaluevalue-jsonpath-str)
- [rust - jsonpath::select_str(json_str: &str, jsonpath: &str)](#rust---jsonpathselect_strjson-str-jsonpath-str)
- [rust - jsonpath::compile(jsonpath: &str)](#rust---jsonpathcompilejsonpath-str)
- [rust - jsonpath::selector(json: &serde_json::value::Value)](#rust---jsonpathselectorjson-serde_jsonvaluevalue)
- [rust - examples](https://github.com/freestrings/jsonpath/wiki/rust-examples)
@ -36,6 +37,7 @@ To enjoy Rust!
[With AWS API Gateway](#)
[Simple time check - webassembly](https://github.com/freestrings/jsonpath/wiki/Simple-timecheck---jsonpath-wasm)
[Simple time check - native addon for NodeJs](https://github.com/freestrings/jsonpath/wiki/Simple-timecheck-jsonpath-native)
## With Javascript
@ -192,7 +194,7 @@ extern crate jsonpath_lib as jsonpath;
extern crate serde_json;
```
### rust - jsonpath::select(&json: serde_json::value::Value, jsonpath: &str)
### rust - jsonpath::select(json: &serde_json::value::Value, jsonpath: &str)
```rust
let json_obj = json!({
@ -206,6 +208,21 @@ let ret = json!([ {"id": 0}, {"id": 0} ]);
assert_eq!(json, ret)
```
### rust - jsonpath::select_str(json: &str, jsonpath: &str)
```rust
let json_obj = json!({
"school": {
"friends": [{"id": 0}, {"id": 1}]
},
"friends": [{"id": 0}, {"id": 1}]
});
let json_str = jsonpath::select_str(&serde_json::to_string(&json_obj).unwrap(), "$..friends[0]").unwrap();
let json: Value = serde_json::from_str(&json_str).unwrap();
let ret = json!([ {"id": 0}, {"id": 0} ]);
assert_eq!(json, ret)
```
### rust - jsonpath::compile(jsonpath: &str)
```rust

View File

@ -14,39 +14,56 @@ fn read_json(path: &str) -> String {
contents
}
fn get_string() -> String {
read_json("./benches/example.json")
}
fn get_json() -> Value {
let string = get_string();
serde_json::from_str(string.as_str()).unwrap()
}
fn get_path() -> &'static str {
r#"$..book[?(@.price<30 && @.category=="fiction")]"#
}
#[bench]
fn bench_selector(b: &mut Bencher) {
let string = read_json("./benches/example.json");
let path = r#"$..book[?(@.price<30 && @.category=="fiction")]"#;
let json: Value = serde_json::from_str(string.as_str()).unwrap();
let json = get_json();
let mut selector = jsonpath::selector(&json);
b.iter(move || {
for _ in 1..1000 {
let _ = selector(path).unwrap();
for _ in 1..100 {
let _ = selector(get_path()).unwrap();
}
});
}
#[bench]
fn bench_select(b: &mut Bencher) {
let string = read_json("./benches/example.json");
let path = r#"$..book[?(@.price<30 && @.category=="fiction")]"#;
let json: Value = serde_json::from_str(string.as_str()).unwrap();
fn bench_select_val(b: &mut Bencher) {
let json = get_json();
b.iter(move || {
for _ in 1..1000 {
let _ = jsonpath::select(&json, path).unwrap();
for _ in 1..100 {
let _ = jsonpath::select(&json, get_path()).unwrap();
}
});
}
#[bench]
fn bench_select_str(b: &mut Bencher) {
let json = get_string();
b.iter(move || {
for _ in 1..100 {
let _ = jsonpath::select_str(&json, get_path()).unwrap();
}
});
}
#[bench]
fn bench_compile(b: &mut Bencher) {
let string = read_json("./benches/example.json");
let path = r#"$..book[?(@.price<30 && @.category=="fiction")]"#;
let json: Value = serde_json::from_str(string.as_str()).unwrap();
let mut template = jsonpath::compile(path);
let json = get_json();
let mut template = jsonpath::compile(get_path());
b.iter(move || {
for _ in 1..1000 {
for _ in 1..100 {
let _ = template(&json).unwrap();
}
});

3
benches/package-lock.json generated Normal file
View File

@ -0,0 +1,3 @@
{
"lockfileVersion": 1
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -88,11 +88,11 @@
/******/ "__wbindgen_throw": function(p0i32,p1i32) {
/******/ return installedModules["../browser_pkg/jsonpath_wasm.js"].exports["__wbindgen_throw"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_closure_wrapper99": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../browser_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper99"](p0i32,p1i32,p2i32);
/******/ "__wbindgen_closure_wrapper100": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../browser_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper100"](p0i32,p1i32,p2i32);
/******/ },
/******/ "__wbindgen_closure_wrapper101": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../browser_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper101"](p0i32,p1i32,p2i32);
/******/ "__wbindgen_closure_wrapper102": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../browser_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper102"](p0i32,p1i32,p2i32);
/******/ }
/******/ }
/******/ };
@ -192,7 +192,7 @@
/******/ promises.push(installedWasmModuleData);
/******/ else {
/******/ var importObject = wasmImportObjects[wasmModuleId]();
/******/ var req = fetch(__webpack_require__.p + "" + {"../browser_pkg/jsonpath_wasm_bg.wasm":"db8564aae9d99ec41b79"}[wasmModuleId] + ".module.wasm");
/******/ var req = fetch(__webpack_require__.p + "" + {"../browser_pkg/jsonpath_wasm_bg.wasm":"e354e10adee0b37b85d7"}[wasmModuleId] + ".module.wasm");
/******/ var promise;
/******/ if(importObject instanceof Promise && typeof WebAssembly.compileStreaming === 'function') {
/******/ promise = Promise.all([WebAssembly.compileStreaming(req), importObject]).then(function(items) {

Binary file not shown.

10
docs/bootstrap.js vendored
View File

@ -88,11 +88,11 @@
/******/ "__wbindgen_throw": function(p0i32,p1i32) {
/******/ return installedModules["../browser_pkg/jsonpath_wasm.js"].exports["__wbindgen_throw"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_closure_wrapper99": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../browser_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper99"](p0i32,p1i32,p2i32);
/******/ "__wbindgen_closure_wrapper100": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../browser_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper100"](p0i32,p1i32,p2i32);
/******/ },
/******/ "__wbindgen_closure_wrapper101": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../browser_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper101"](p0i32,p1i32,p2i32);
/******/ "__wbindgen_closure_wrapper102": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../browser_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper102"](p0i32,p1i32,p2i32);
/******/ }
/******/ }
/******/ };
@ -192,7 +192,7 @@
/******/ promises.push(installedWasmModuleData);
/******/ else {
/******/ var importObject = wasmImportObjects[wasmModuleId]();
/******/ var req = fetch(__webpack_require__.p + "" + {"../browser_pkg/jsonpath_wasm_bg.wasm":"db8564aae9d99ec41b79"}[wasmModuleId] + ".module.wasm");
/******/ var req = fetch(__webpack_require__.p + "" + {"../browser_pkg/jsonpath_wasm_bg.wasm":"e354e10adee0b37b85d7"}[wasmModuleId] + ".module.wasm");
/******/ var promise;
/******/ if(importObject instanceof Promise && typeof WebAssembly.compileStreaming === 'function') {
/******/ promise = Promise.all([WebAssembly.compileStreaming(req), importObject]).then(function(items) {

Binary file not shown.

View File

@ -6,7 +6,7 @@ function compile(path) {
if(typeof json != 'string') {
json = JSON.stringify(json)
}
return compile.template(json);
return JSON.parse(compile.template(json));
};
}
@ -16,7 +16,7 @@ function selector(json) {
}
let selector = new Selector(json);
return (path) => {
return selector.selector(path);
return JSON.parse(selector.selector(path));
}
}
@ -24,7 +24,7 @@ function select(json, path) {
if(typeof json != 'string') {
json = JSON.stringify(json)
}
return selectStr(json, path);
return JSON.parse(selectStr(json, path));
}
module.exports = {

View File

@ -1,6 +1,6 @@
[package]
name = "jsonpath-rs"
version = "0.1.0"
version = "0.1.1"
authors = ["Changseok Han <freestrings@gmail.com>"]
description = "JsonPath engine for NodeJs with Rust native implementation."
keywords = ["library", "jsonpath", "json"]

View File

@ -24,13 +24,9 @@ fn select(mut ctx: FunctionContext) -> JsResult<JsValue> {
fn select_str(mut ctx: FunctionContext) -> JsResult<JsValue> {
let json_val = ctx.argument::<JsString>(0)?.value();
let json: Value = match serde_json::from_str(json_val.as_str()) {
Ok(json) => json,
Err(e) => panic!("{:?}", e)
};
let path = ctx.argument::<JsString>(1)?.value();
match jsonpath::select(&json, path.as_str()) {
Ok(value) => Ok(neon_serde::to_value(&mut ctx, &value)?),
match jsonpath::select_str(&json_val, path.as_str()) {
Ok(value) => Ok(JsString::new(&mut ctx, &value).upcast()),
Err(e) => panic!("{:?}", e)
}
}
@ -66,31 +62,30 @@ declare_types! {
this.node.clone()
};
// let o = ctx.argument::<JsValue>(0)?;
// let json: Value = neon_serde::from_value(&mut ctx, o)?;
let json_str = ctx.argument::<JsString>(0)?.value();
let json: Value = match serde_json::from_str(&json_str) {
Ok(json) => json,
let ref_value: RefValue = match serde_json::from_str(&json_str) {
Ok(ref_value) => ref_value,
Err(e) => panic!("{:?}", e)
};
let mut jf = JsonValueFilter::new_from_value((&json).into());
let mut jf = JsonValueFilter::new_from_value(ref_value.into());
jf.visit(node);
let v = jf.take_value().into_value();
Ok(neon_serde::to_value(&mut ctx, &v)?)
match serde_json::to_string(&jf.take_value()) {
Ok(json_str) => Ok(JsString::new(&mut ctx, &json_str).upcast()),
Err(e) => panic!("{:?}", e)
}
}
}
pub class JsSelector for Selector {
init(mut ctx) {
// let o = ctx.argument::<JsValue>(0)?;
// let json: Value = neon_serde::from_value(&mut ctx, o)?;
let json_str = ctx.argument::<JsString>(0)?.value();
let json: Value = match serde_json::from_str(&json_str) {
Ok(json) => json,
let ref_value: RefValue = match serde_json::from_str(&json_str) {
Ok(ref_value) => ref_value,
Err(e) => panic!("{:?}", e)
};
Ok(Selector { json: (&json).into() })
Ok(Selector { json: ref_value.into() })
}
method selector(mut ctx) {
@ -112,8 +107,10 @@ declare_types! {
let mut jf = JsonValueFilter::new_from_value(json);
jf.visit(node);
let v = jf.take_value().into_value();
Ok(neon_serde::to_value(&mut ctx, &v)?)
match serde_json::to_string(&jf.take_value()) {
Ok(json_str) => Ok(JsString::new(&mut ctx, &json_str).upcast()),
Err(e) => panic!("{:?}", e)
}
}
}
}

View File

@ -4,7 +4,7 @@ describe('compile test', () => {
it('basic', (done) => {
let template = jsonpath.compile('$.a');
let result = template({'a': 1});
if (result == 1) {
if (result === 1) {
done();
}
});
@ -14,7 +14,7 @@ describe('selector test', () => {
it('basic', (done) => {
let selector = jsonpath.selector({'a': 1});
let result = selector('$.a');
if (result == 1) {
if (result === 1) {
done();
}
});
@ -23,7 +23,7 @@ describe('selector test', () => {
describe('select test', () => {
it('basic', (done) => {
let result = jsonpath.select({'a': 1}, '$.a');
if (result == 1) {
if (result === 1) {
done();
}
});

View File

@ -66,7 +66,7 @@ impl TermContext {
}
}
TermContext::Json(_, v) => {
TermContext::Json(None, ValueWrapper::new(v.clone_val(), false))
TermContext::Json(None, ValueWrapper::new(v.get_val().clone(), false))
}
}
}
@ -79,7 +79,7 @@ impl TermContext {
}
}
_ => {
TermContext::Json(None, ValueWrapper::new(v.clone_val(), false))
TermContext::Json(None, ValueWrapper::new(v.get_val().clone(), false))
}
}
}

View File

@ -1,13 +1,13 @@
use std::error::Error;
use std::result::Result;
use std::ops::Deref;
use serde_json::Value;
use ref_value::*;
use parser::prelude::*;
use filter::term::*;
use filter::value_wrapper::*;
use parser::prelude::*;
use ref_value::model::*;
trait ArrayIndex {
fn index(&self, v: &RefValueWrapper) -> usize;
@ -15,7 +15,7 @@ trait ArrayIndex {
fn take_value(&self, v: &RefValueWrapper) -> RefValueWrapper {
let idx = self.index(v);
match v.get(idx) {
Some(v) => v,
Some(v) => v.clone(),
_ => RefValue::Null.into()
}
}
@ -66,7 +66,7 @@ impl ValueFilter {
ValueFilter { vw: ValueWrapper::new(v, is_leaves), last_key: None, filter_mode }
}
fn iter_to_value_vec<'a, I: Iterator<Item=&'a TypeRefValue>>(iter: I) -> Vec<TypeRefValue> {
fn iter_to_value_vec<'a, I: Iterator<Item=&'a RefValueWrapper>>(iter: I) -> Vec<RefValueWrapper> {
iter
.map(|v| v.clone())
.filter(|v| !v.is_null())
@ -98,8 +98,8 @@ impl ValueFilter {
}
}
fn collect_all(key: Option<&String>, v: &RefValueWrapper, buf: &mut Vec<TypeRefValue>) {
match v.get_data_ref() {
fn collect_all(key: Option<&String>, v: &RefValueWrapper, buf: &mut Vec<RefValueWrapper>) {
match v.deref() {
RefValue::Array(vec) => {
if key.is_none() {
for v in vec {
@ -107,7 +107,7 @@ impl ValueFilter {
}
}
for i in vec {
Self::collect_all(key, &i.into(), buf);
Self::collect_all(key, i, buf);
}
}
RefValue::Object(v) => {
@ -120,7 +120,7 @@ impl ValueFilter {
}
}
for (_, v) in v.into_iter() {
Self::collect_all(key, &v.into(), buf);
Self::collect_all(key, v, buf);
}
}
_ => {}
@ -154,7 +154,7 @@ impl ValueFilter {
pub fn step_in_all(&mut self) -> &ValueWrapper {
debug!("step_in_all");
let vec = match self.vw.get_val().get_data_ref() {
let vec = match self.vw.get_val().deref() {
RefValue::Object(ref map) => {
Self::iter_to_value_vec(map.values())
}
@ -162,12 +162,12 @@ impl ValueFilter {
Self::iter_to_value_vec(list.iter())
}
RefValue::Null => Vec::new(),
_ => vec![self.vw.get_val().clone_data()]
_ => vec![self.vw.get_val().clone()]
};
self.last_key = Some(ValueFilterKey::All);
self.vw.replace(RefValue::Array(vec).into());
trace!("step_in_all - {:?}", self.vw.get_val().get_data_ref());
trace!("step_in_all - {:?}", self.vw.get_val());
&self.vw
}
@ -176,17 +176,17 @@ impl ValueFilter {
trace!("step_in_num - before: leaves {}, filterMode {} - {:?}"
, self.vw.is_leaves()
, self.filter_mode
, self.vw.get_val().get_data_ref());
, self.vw.get_val());
let v = if self.vw.is_leaves() {
let filter_mode = self.filter_mode;
match self.vw.get_val().get_data_ref() {
match self.vw.get_val().deref() {
RefValue::Array(ref vec) => {
let mut ret = Vec::new();
for v in vec {
let wrapper = Self::get_nested_array(&v.into(), *key, filter_mode);
let wrapper = Self::get_nested_array(v, *key, filter_mode);
if !wrapper.is_null() {
ret.push(wrapper.clone_data());
ret.push(wrapper.clone());
}
}
RefValue::Array(ret).into()
@ -199,7 +199,7 @@ impl ValueFilter {
self.last_key = Some(ValueFilterKey::Num(key.index(&v)));
self.vw.replace(v);
trace!("step_in_num - after: {:?}", self.vw.get_val().get_data_ref());
trace!("step_in_num - after: {:?}", self.vw.get_val());
&self.vw
}
@ -212,28 +212,27 @@ impl ValueFilter {
trace!("step_in_string - before: {},{},{:?}"
, self.vw.is_leaves()
, self.filter_mode
, self.vw.get_val().get_data_ref());
, self.vw.get_val());
let filter_mode = self.filter_mode;
let is_leaves = self.vw.is_leaves();
let val = match self.vw.get_val().get_data_ref() {
let val = match self.vw.get_val().deref() {
RefValue::Array(ref vec) if is_leaves => {
let mut buf = Vec::new();
for mut v in vec {
let wrapper: RefValueWrapper = v.into();
if wrapper.is_array() {
let vec = wrapper.as_array().unwrap();
if v.is_array() {
let vec = v.as_array().unwrap();
let mut ret = Vec::new();
for v in vec {
let nested_wrapper = Self::get_nested_object(&v.into(), key, filter_mode);
let nested_wrapper = Self::get_nested_object(v, key, filter_mode);
if !nested_wrapper.is_null() {
ret.push(nested_wrapper.clone_data());
ret.push(nested_wrapper.clone());
}
}
buf.append(&mut ret);
} else {
match wrapper.get(key.clone()) {
Some(v) => buf.push(v.clone_data()),
match v.get(key.clone()) {
Some(v) => buf.push(v.clone()),
_ => {}
}
}
@ -244,9 +243,9 @@ impl ValueFilter {
RefValue::Array(ref vec) if !is_leaves => {
let mut ret = Vec::new();
for v in vec {
let wrapper = Self::get_nested_object(&v.into(), key, filter_mode);
let wrapper = Self::get_nested_object(v, key, filter_mode);
if !wrapper.is_null() {
ret.push(wrapper.clone_data());
ret.push(wrapper.clone());
}
}
RefValue::Array(ret).into()
@ -264,7 +263,7 @@ impl ValueFilter {
trace!("step_in_string - after: {},{},{:?}"
, self.vw.is_leaves()
, self.filter_mode
, self.vw.get_val().get_data_ref());
, self.vw.get_val());
&self.vw
}
}
@ -304,7 +303,7 @@ impl JsonValueFilter {
if from_current {
self.filter_stack.last()
.map(|vf| {
ValueFilter::new(vf.vw.clone_val(), vf.vw.is_leaves(), from_current)
ValueFilter::new(vf.vw.get_val().clone(), vf.vw.is_leaves(), from_current)
})
.and_then(|vf| {
Some(self.filter_stack.push(vf))
@ -334,10 +333,10 @@ impl JsonValueFilter {
}
}
pub fn current_value(&self) -> RefValueWrapper {
pub fn into_value(&self) -> Value {
match self.filter_stack.last() {
Some(v) => v.vw.get_val().clone(),
_ => RefValue::Null.into()
Some(v) => v.vw.into_value(),
_ => Value::Null
}
}
@ -354,12 +353,12 @@ impl JsonValueFilter {
match self.filter_stack.last_mut() {
Some(ref mut vf) if vf.vw.is_array() && vf.vw.is_leaves() => {
let mut ret = Vec::new();
if let RefValue::Array(val) = vf.vw.get_val().get_data_ref() {
if let RefValue::Array(val) = vf.vw.get_val().deref() {
for mut v in val {
for i in &indices {
let v = i.take_value(&v.into());
let v = i.take_value(v);
if !v.is_null() {
ret.push(v.clone_data());
ret.push(v.clone());
}
}
}
@ -371,7 +370,7 @@ impl JsonValueFilter {
for i in indices {
let wrapper = i.take_value(&vf.vw.get_val());
if !wrapper.is_null() {
ret.push(wrapper.clone_data());
ret.push(wrapper.clone());
}
}
vf.vw.replace(RefValue::Array(ret).into());
@ -391,7 +390,7 @@ impl JsonValueFilter {
let to = match to {
Some(v) => v.index(val),
_ => {
if let RefValue::Array(v) = val.get_data_ref() {
if let RefValue::Array(v) = val.deref() {
v.len()
} else {
0
@ -401,24 +400,23 @@ impl JsonValueFilter {
(from, to)
}
fn _range(from: usize, to: usize, v: &RefValueWrapper) -> Vec<TypeRefValue> {
fn _range(from: usize, to: usize, v: &RefValueWrapper) -> Vec<RefValueWrapper> {
trace!("range - {}:{}", from, to);
(from..to).into_iter()
.map(|i| i.take_value(v))
.filter(|v| !v.is_null())
.map(|v| v.clone_data())
.map(|v| v.clone())
.collect()
}
match self.filter_stack.last_mut() {
Some(ref mut vf) if vf.vw.is_array() && vf.vw.is_leaves() => {
let mut buf = Vec::new();
if let RefValue::Array(vec) = vf.vw.get_val().get_data_ref() {
if let RefValue::Array(vec) = vf.vw.get_val().deref() {
for mut v in vec {
let wrapper = v.into();
let (from, to) = _from_to(from, to, &wrapper);
let mut v: Vec<TypeRefValue> = _range(from, to, &wrapper);
let (from, to) = _from_to(from, to, v);
let mut v: Vec<RefValueWrapper> = _range(from, to, v);
buf.append(&mut v);
}
}
@ -426,7 +424,7 @@ impl JsonValueFilter {
}
Some(ref mut vf) if vf.vw.is_array() && !vf.vw.is_leaves() => {
let (from, to) = _from_to(from, to, &vf.vw.get_val());
let vec: Vec<TypeRefValue> = _range(from, to, vf.vw.get_val());
let vec: Vec<RefValueWrapper> = _range(from, to, vf.vw.get_val());
vf.vw.replace(RefValue::Array(vec).into());
}
_ => {}
@ -489,7 +487,7 @@ impl JsonValueFilter {
match self.filter_stack.pop() {
Some(mut vf) => {
let is_leaves = vf.vw.is_leaves();
match vf.vw.get_val().get_data_ref() {
match vf.vw.get_val().deref() {
RefValue::Null | RefValue::Bool(false) => {
self.replace_filter_stack(RefValue::Null.into(), is_leaves);
}

View File

@ -1,6 +1,9 @@
use indexmap::map::IndexMap;
use std::ops::Deref;
use ref_value::*;
use indexmap::IndexSet;
use serde_json::Value;
use ref_value::model::*;
use super::cmp::*;
use super::term::*;
@ -40,7 +43,7 @@ impl ValueWrapper {
}
fn cmp_with_term<F: PrivCmp>(val: &RefValueWrapper, et: &ExprTerm, cmp_fn: &F, default: bool, reverse: bool) -> bool {
match val.get_data_ref() {
match val.deref() {
RefValue::Bool(ref v1) => {
match et {
ExprTerm::Bool(v2) => if reverse { cmp_fn.cmp_bool(v2, v1) } else { cmp_fn.cmp_bool(v1, v2) },
@ -63,10 +66,10 @@ impl ValueWrapper {
fn take_object_in_array<F: PrivCmp>(&self, key: &String, et: &ExprTerm, cmp: &F, reverse: bool) -> Option<Self> {
fn _filter_with_object<F: Fn(&RefValueWrapper) -> bool>(v: &RefValueWrapper, key: &String, fun: F) -> bool {
match v.get_data_ref() {
match v.deref() {
RefValue::Object(map) => {
match map.get(key) {
Some(val) => fun(&val.into()),
Some(val) => fun(val),
_ => false
}
}
@ -74,11 +77,11 @@ impl ValueWrapper {
}
}
match self.val.get_data_ref() {
match self.val.deref() {
RefValue::Array(vec) => {
let mut ret = Vec::new();
for v in vec {
if _filter_with_object(&v.into(), key, |vv| {
if _filter_with_object(v, key, |vv| {
Self::cmp_with_term(vv, et, cmp, false, reverse)
}) {
ret.push(v.clone());
@ -104,11 +107,11 @@ impl ValueWrapper {
match self.take_with_key_type(key, et, &cmp, reverse) {
Some(vw) => vw,
_ => {
match self.val.get_data_ref() {
match &(*self.val) {
RefValue::Array(vec) => {
let mut ret = Vec::new();
for v in vec {
if Self::cmp_with_term(&v.into(), et, &cmp, false, reverse) {
if Self::cmp_with_term(v, et, &cmp, false, reverse) {
ret.push(v.clone());
}
}
@ -127,14 +130,13 @@ impl ValueWrapper {
}
pub fn replace(&mut self, val: RefValueWrapper) {
let is_null = match val.get_data_ref() {
let is_null = match val.deref() {
RefValue::Array(v) => if v.is_empty() { true } else { false },
RefValue::Object(m) => if m.is_empty() { true } else { false },
_ => val.is_null()
};
self.val = if is_null {
let v = RefValueWrapper::wrap(RefValue::Null);
RefValueWrapper::new(v)
RefValue::Null.into()
} else {
val
};
@ -144,135 +146,98 @@ impl ValueWrapper {
&self.val
}
pub fn clone_val(&self) -> RefValueWrapper {
self.val.clone()
pub fn into_value(&self) -> Value {
self.get_val().into()
}
pub fn is_array(&self) -> bool {
self.val.is_array()
}
fn uuid(v: &RefValueWrapper) -> String {
fn _fn(v: &RefValueWrapper, acc: &mut String) {
match v.get_data_ref() {
RefValue::Null => acc.push_str("null"),
RefValue::String(v) => acc.push_str(v),
RefValue::Bool(v) => acc.push_str(if *v { "true" } else { "false" }),
RefValue::Number(v) => acc.push_str(&*v.to_string()),
RefValue::Array(v) => {
for (i, v) in v.iter().enumerate() {
acc.push_str(&*i.to_string());
_fn(&v.into(), acc);
}
}
RefValue::Object(ref v) => {
for (k, v) in v.into_iter() {
acc.push_str(&*k.to_string());
_fn(&v.into(), acc);
}
}
}
}
let mut acc = String::new();
_fn(v, &mut acc);
acc
}
fn into_map(&self) -> IndexMap<String, RefValueWrapper> {
let mut map = IndexMap::new();
match self.val.get_data_ref() {
fn into_hashset(&self) -> IndexSet<RefValueWrapper> {
let mut hashset = IndexSet::new();
match self.val.deref() {
RefValue::Array(ref v1) => {
for v in v1 {
let wrapper = v.into();
let key = Self::uuid(&wrapper);
map.insert(key, wrapper);
hashset.insert(v.clone());
}
}
_ => {
map.insert(Self::uuid(&self.val), self.val.clone());
hashset.insert(self.val.clone());
}
}
map
hashset
}
pub fn except(&self, other: &Self) -> Self {
let map = self.into_map();
let mut ret: IndexMap<String, RefValueWrapper> = IndexMap::new();
match other.val.get_data_ref() {
let hashset = self.into_hashset();
let mut ret: IndexSet<RefValueWrapper> = IndexSet::new();
match &(*other.val) {
RefValue::Array(ref v1) => {
for v in v1 {
let wrapper = v.into();
let key = Self::uuid(&wrapper);
if !map.contains_key(&key) {
ret.insert(key, wrapper);
if !hashset.contains(v) {
ret.insert(v.clone());
}
}
}
_ => {
let key = Self::uuid(&other.val);
if !map.contains_key(&key) {
ret.insert(key, other.val.clone());
if !hashset.contains(&other.val) {
ret.insert(other.val.clone());
}
}
}
let vec = ret.values().into_iter().map(|v| v.clone_data()).collect();
let vec = ret.into_iter().map(|v| v.clone()).collect();
ValueWrapper::new(RefValue::Array(vec).into(), false)
}
pub fn intersect(&self, other: &Self) -> Self {
let map = self.into_map();
let mut ret: IndexMap<String, RefValueWrapper> = IndexMap::new();
match other.val.get_data_ref() {
let hashset = self.into_hashset();
let mut ret: IndexSet<RefValueWrapper> = IndexSet::new();
match other.val.deref() {
RefValue::Array(ref v1) => {
for v in v1 {
let wrapper = v.into();
let key = Self::uuid(&wrapper);
if map.contains_key(&key) {
ret.insert(key, wrapper);
if hashset.contains(v) {
ret.insert(v.clone());
}
}
}
_ => {
let key = Self::uuid(&other.val);
if map.contains_key(&key) {
ret.insert(key, other.val.clone());
if hashset.contains(&other.val) {
ret.insert(other.val.clone());
}
}
}
let vec = ret.values().into_iter().map(|v| v.clone_data()).collect();
let vec = ret.into_iter().map(|v| v.clone()).collect();
ValueWrapper::new(RefValue::Array(vec).into(), false)
}
pub fn union(&self, other: &Self) -> Self {
let mut map = self.into_map();
match other.val.get_data_ref() {
let mut hashset = self.into_hashset();
match other.val.deref() {
RefValue::Array(ref v1) => {
for v in v1 {
let wrapper = v.into();
let key = Self::uuid(&wrapper);
if !map.contains_key(&key) {
map.insert(key, wrapper);
if !hashset.contains(v) {
hashset.insert(v.clone());
}
}
}
_ => {
let key = Self::uuid(&other.val);
if !map.contains_key(&key) {
map.insert(key, other.val.clone());
if !hashset.contains(&other.val) {
hashset.insert(other.val.clone());
}
}
}
let mut vw = ValueWrapper::new(RefValue::Null.into(), false);
let list = map.values().into_iter().map(|val| val.clone_data()).collect();
let list = hashset.into_iter().map(|val| val.clone()).collect();
vw.replace(RefValue::Array(list).into());
vw
}
pub fn into_term(&self, key: &Option<ValueFilterKey>) -> TermContext {
match self.val.get_data_ref() {
match self.val.deref() {
RefValue::String(ref s) => TermContext::Constants(ExprTerm::String(s.clone())),
RefValue::Number(ref n) => TermContext::Constants(ExprTerm::Number(n.as_f64().unwrap())),
RefValue::Bool(b) => TermContext::Constants(ExprTerm::Bool(*b)),
@ -284,13 +249,12 @@ impl ValueWrapper {
}
pub fn filter(&self, key: &Option<ValueFilterKey>) -> Self {
let v = match self.val.get_data_ref() {
let v = match self.val.deref() {
RefValue::Array(ref vec) => {
let mut ret = Vec::new();
for v in vec {
if let Some(ValueFilterKey::String(k)) = key {
let wrapper: RefValueWrapper = v.into();
if wrapper.get(k.clone()).is_some() {
if v.get(k.clone()).is_some() {
ret.push(v.clone());
}
}
@ -300,7 +264,7 @@ impl ValueWrapper {
RefValue::Object(ref map) => {
match key {
Some(ValueFilterKey::String(k)) => match map.get(k) {
Some(v) => v.into(),
Some(v) => v.clone(),
_ => RefValue::Null.into()
},
_ => RefValue::Null.into()

View File

@ -158,11 +158,18 @@
//! assert_eq!(ret, json);
//! ```
extern crate env_logger;
extern crate indexmap;
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate serde;
extern crate serde_json;
extern crate indexmap;
use std::result;
use serde_json::Value;
use prelude::*;
#[doc(hidden)]
mod parser;
@ -172,14 +179,6 @@ mod filter;
mod ref_value;
pub mod prelude;
use parser::prelude::*;
use filter::prelude::*;
use std::result;
use serde_json::Value;
use ref_value::*;
type Result = result::Result<Value, String>;
/// # Read multiple Json multiple times with the same JsonPath
@ -222,7 +221,7 @@ pub fn compile<'a>(path: &'a str) -> impl FnMut(&Value) -> Result + 'a {
Ok(n) => {
let mut jf = JsonValueFilter::new_from_value(json.into());
jf.visit(n.clone());
Ok(jf.take_value().into_value())
Ok(jf.take_value().into())
}
Err(e) => Err(e.clone())
}
@ -259,7 +258,7 @@ pub fn selector(json: &Value) -> impl FnMut(&str) -> Result {
let mut jf = JsonValueFilter::new_from_value(wrapper.clone());
let mut parser = Parser::new(path);
parser.parse(&mut jf)?;
Ok(jf.take_value().into_value())
Ok(jf.take_value().into())
}
}
@ -288,7 +287,7 @@ pub fn select(json: &Value, path: &str) -> Result {
let mut jf = JsonValueFilter::new_from_value(json.into());
let mut parser = Parser::new(path);
parser.parse(&mut jf)?;
Ok(jf.take_value().into_value())
Ok(jf.take_value().into())
}
/// # Read Json using JsonPath - Deprecated. use select
@ -296,3 +295,29 @@ pub fn read(json: &Value, path: &str) -> Result {
select(json, path)
}
/// # Read Json string using JsonPath
///
/// ```rust
/// extern crate jsonpath_lib as jsonpath;
/// #[macro_use] extern crate serde_json;
///
/// use serde_json::Value;
///
/// let json_obj = json!({
/// "school": {
/// "friends": [{"id": 0}, {"id": 1}]
/// },
/// "friends": [{"id": 0}, {"id": 1}]
/// });
/// let json_str = jsonpath::select_str(&serde_json::to_string(&json_obj).unwrap(), "$..friends[0]").unwrap();
/// let json: Value = serde_json::from_str(&json_str).unwrap();
/// let ret = json!([ {"id": 0}, {"id": 0} ]);
/// assert_eq!(json, ret);
/// ```
pub fn select_str(json: &str, path: &str) -> result::Result<String, String> {
let ref_value: RefValue = serde_json::from_str(json).map_err(|e| format!("{:?}", e))?;
let mut jf = JsonValueFilter::new_from_value(ref_value.into());
let mut parser = Parser::new(path);
parser.parse(&mut jf)?;
serde_json::to_string(&jf.take_value()).map_err(|e| format!("{:?}", e))
}

View File

@ -1,3 +1,3 @@
pub use parser::prelude::*;
pub use filter::prelude::*;
pub use ref_value::*;
pub use ref_value::model::*;

111
src/ref_value/convert.rs Normal file
View File

@ -0,0 +1,111 @@
use std::ops::Deref;
use indexmap::IndexMap;
use serde_json::Value;
use ref_value::model::{RefValue, RefValueWrapper};
pub struct RefValueConverter;
impl RefValueConverter {
pub fn new(value: &Value) -> RefValueWrapper {
RefValueConverter {}.visit_value(value)
}
fn visit_value(&self, value: &Value) -> RefValueWrapper {
match value {
Value::Null => self.visit_null(),
Value::Bool(v) => self.visit_bool(v),
Value::Number(v) => self.visit_number(v),
Value::String(v) => self.visit_string(v),
Value::Array(v) => self.visit_array(v),
Value::Object(v) => self.visit_object(v),
}
}
fn visit_null(&self) -> RefValueWrapper {
RefValue::Null.into()
}
fn visit_bool(&self, value: &bool) -> RefValueWrapper {
RefValue::Bool(*value).into()
}
fn visit_number(&self, value: &serde_json::Number) -> RefValueWrapper {
RefValue::Number(value.clone()).into()
}
fn visit_string(&self, value: &String) -> RefValueWrapper {
RefValue::String(value.to_string()).into()
}
fn visit_array(&self, value: &Vec<Value>) -> RefValueWrapper {
let mut values = Vec::new();
for v in value {
values.push(self.visit_value(v));
}
RefValue::Array(values).into()
}
fn visit_object(&self, value: &serde_json::Map<String, Value>) -> RefValueWrapper {
let mut map = IndexMap::new();
for (key, _) in value {
let value = self.visit_value(match value.get(key) {
Some(v) => v,
_ => &Value::Null
});
map.insert(key.clone(), value);
}
RefValue::Object(map).into()
}
}
pub struct ValueConverter;
impl ValueConverter {
pub fn new(value: &RefValueWrapper) -> Value {
ValueConverter {}.visit_value(value)
}
fn visit_value(&self, value: &RefValueWrapper) -> Value {
match value.deref() {
RefValue::Null => self.visit_null(),
RefValue::Bool(v) => self.visit_bool(v),
RefValue::Number(v) => self.visit_number(v),
RefValue::String(v) => self.visit_string(v),
RefValue::Array(v) => self.visit_array(v),
RefValue::Object(v) => self.visit_object(v),
}
}
fn visit_null(&self) -> Value {
Value::Null
}
fn visit_bool(&self, value: &bool) -> Value {
Value::Bool(*value)
}
fn visit_number(&self, value: &serde_json::Number) -> Value {
Value::Number(value.clone())
}
fn visit_string(&self, value: &String) -> Value {
Value::String(value.clone())
}
fn visit_array(&self, value: &Vec<RefValueWrapper>) -> Value {
let mut values = Vec::new();
for v in value {
values.push(self.visit_value(v));
}
Value::Array(values)
}
fn visit_object(&self, map: &IndexMap<String, RefValueWrapper>) -> Value {
let mut ret = serde_json::Map::new();
let tmp_null = &RefValue::Null.into();
for (k, _) in map {
let value = self.visit_value(match map.get(k) {
Some(e) => e,
_ => tmp_null
});
ret.insert(k.to_string(), value);
}
Value::Object(ret)
}
}

119
src/ref_value/de.rs Normal file
View File

@ -0,0 +1,119 @@
use std::error::Error;
use std::fmt;
use std::result::Result;
use indexmap::IndexMap;
use serde::{Deserialize, Deserializer};
use serde::de::{MapAccess, SeqAccess, Visitor};
use serde_json::Value;
use super::model::*;
impl<'de> Deserialize<'de> for RefValue {
fn deserialize<D>(deserializer: D) -> Result<RefValue, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(RefValueVisitor {})
}
}
struct RefValueVisitor {}
impl<'de> Visitor<'de> for RefValueVisitor {
type Value = RefValue;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("any valid JSON value")
}
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: Error, {
Ok(RefValue::Bool(v))
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(RefValue::Number(v.into()))
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(RefValue::Number(v.into()))
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error, {
let n: Value = v.into();
if let Value::Number(n) = n {
Ok(RefValue::Number(n))
} else {
unreachable!()
}
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error, {
self.visit_string(String::from(v))
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(RefValue::String(v))
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(RefValue::Null)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error> where
D: Deserializer<'de>, {
Deserialize::deserialize(deserializer)
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error, {
Ok(RefValue::Null)
}
fn visit_seq<A>(self, mut visitor: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>, {
let mut vec = Vec::new();
while let Some(elem) = visitor.next_element()? {
let e: RefValue = elem;
let v: RefValueWrapper = e.into();
vec.push(v);
}
Ok(RefValue::Array(vec))
}
fn visit_map<A>(self, mut visitor: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>, {
let mut values = IndexMap::new();
match visitor.next_key() {
Ok(Some(first_key)) => {
let next: RefValue = visitor.next_value()?;
values.insert(first_key, next.into());
while let Some((k, v)) = visitor.next_entry()? {
let value: RefValue = v;
values.insert(k, value.into());
}
Ok(RefValue::Object(values))
}
_ => Ok(RefValue::Object(IndexMap::new())),
}
}
}

View File

@ -1,382 +1,5 @@
extern crate indexmap;
extern crate serde_json;
use std::sync::Arc;
use std::convert::Into;
use indexmap::map::IndexMap;
use serde_json::{Number, Value};
pub type TypeRefValue = Arc<Box<RefValue>>;
impl Into<RefValueWrapper> for TypeRefValue {
fn into(self) -> RefValueWrapper {
RefValueWrapper::new(self.clone())
}
}
impl Into<RefValueWrapper> for &TypeRefValue {
fn into(self) -> RefValueWrapper {
RefValueWrapper::new(self.clone())
}
}
///
/// serde_json::Value 참고
///
pub trait RefIndex {
fn index_into<'v>(&self, v: &'v RefValue) -> Option<&'v TypeRefValue>;
fn index_into_mut<'v>(&self, v: &'v mut RefValue) -> Option<&'v mut TypeRefValue>;
fn index_or_insert<'v>(&self, v: &'v mut RefValue) -> &'v mut TypeRefValue;
}
impl RefIndex for usize {
fn index_into<'v>(&self, v: &'v RefValue) -> Option<&'v TypeRefValue> {
match *v {
RefValue::Array(ref vec) => vec.get(*self),
_ => None,
}
}
fn index_into_mut<'v>(&self, v: &'v mut RefValue) -> Option<&'v mut TypeRefValue> {
match *v {
RefValue::Array(ref mut vec) => vec.get_mut(*self),
_ => None,
}
}
fn index_or_insert<'v>(&self, v: &'v mut RefValue) -> &'v mut TypeRefValue {
match *v {
RefValue::Array(ref mut vec) => {
let len = vec.len();
vec.get_mut(*self).unwrap_or_else(|| {
panic!(
"cannot access index {} of JSON array of length {}",
self, len
)
})
}
_ => panic!("cannot access index {} of JSON {:?}", self, v),
}
}
}
impl RefIndex for str {
fn index_into<'v>(&self, v: &'v RefValue) -> Option<&'v TypeRefValue> {
match *v {
RefValue::Object(ref map) => map.get(self),
_ => None,
}
}
fn index_into_mut<'v>(&self, v: &'v mut RefValue) -> Option<&'v mut TypeRefValue> {
match *v {
RefValue::Object(ref mut map) => map.get_mut(self),
_ => None,
}
}
fn index_or_insert<'v>(&self, v: &'v mut RefValue) -> &'v mut TypeRefValue {
if let RefValue::Null = *v {
*v = RefValue::Object(IndexMap::new());
}
match *v {
RefValue::Object(ref mut map) => {
map.entry(self.to_owned()).or_insert(RefValueWrapper::wrap(RefValue::Null))
}
_ => panic!("cannot access key {:?} in JSON {:?}", self, v),
}
}
}
impl RefIndex for String {
fn index_into<'v>(&self, v: &'v RefValue) -> Option<&'v TypeRefValue> {
self[..].index_into(v)
}
fn index_into_mut<'v>(&self, v: &'v mut RefValue) -> Option<&'v mut TypeRefValue> {
self[..].index_into_mut(v)
}
fn index_or_insert<'v>(&self, v: &'v mut RefValue) -> &'v mut TypeRefValue {
self[..].index_or_insert(v)
}
}
#[derive(Debug)]
pub struct RefValueWrapper {
data: TypeRefValue
}
impl RefValueWrapper {
pub fn new(ref_value: TypeRefValue) -> Self {
RefValueWrapper { data: ref_value }
}
pub fn wrap(ref_val: RefValue) -> TypeRefValue {
Arc::new(Box::new(ref_val))
}
pub fn into_value(&self) -> Value {
ValueConverter::new(&self.data)
}
pub fn clone(&self) -> Self {
RefValueWrapper { data: self.data.clone() }
}
pub fn clone_data(&self) -> TypeRefValue {
self.data.clone()
}
pub fn get<I: RefIndex>(&self, index: I) -> Option<RefValueWrapper> {
index.index_into(&**self.data).map(|v| Self::new(v.clone()))
}
pub fn is_object(&self) -> bool {
(**self.data).is_object()
}
pub fn as_object(&self) -> Option<&IndexMap<String, TypeRefValue>> {
(**self.data).as_object()
}
pub fn is_array(&self) -> bool {
(**self.data).is_array()
}
pub fn as_array(&self) -> Option<&Vec<TypeRefValue>> {
(**self.data).as_array()
}
pub fn is_string(&self) -> bool {
(**self.data).is_string()
}
pub fn as_str(&self) -> Option<&str> {
(**self.data).as_str()
}
pub fn is_number(&self) -> bool {
(**self.data).is_number()
}
pub fn as_number(&self) -> Option<Number> {
(**self.data).as_number()
}
pub fn is_boolean(&self) -> bool {
(**self.data).is_boolean()
}
pub fn as_bool(&self) -> Option<bool> {
(**self.data).as_bool()
}
pub fn is_null(&self) -> bool {
(**self.data).is_null()
}
pub fn as_null(&self) -> Option<()> {
(**self.data).as_null()
}
pub fn get_data_ref(&self) -> &RefValue {
&(**self.data)
}
}
impl Into<RefValueWrapper> for &Value {
fn into(self) -> RefValueWrapper {
let ref_val = RefValueConverter::new(self);
RefValueWrapper::new(ref_val)
}
}
#[derive(Debug)]
pub enum RefValue {
Null,
Bool(bool),
Number(Number),
String(String),
Array(Vec<TypeRefValue>),
Object(IndexMap<String, TypeRefValue>),
}
impl RefValue {
pub fn get<I: RefIndex>(&self, index: I) -> Option<&TypeRefValue> {
index.index_into(self)
}
pub fn is_object(&self) -> bool {
self.as_object().is_some()
}
pub fn as_object(&self) -> Option<&IndexMap<String, TypeRefValue>> {
match *self {
RefValue::Object(ref map) => Some(map),
_ => None,
}
}
pub fn is_array(&self) -> bool {
self.as_array().is_some()
}
pub fn as_array(&self) -> Option<&Vec<TypeRefValue>> {
match *self {
RefValue::Array(ref array) => Some(&*array),
_ => None,
}
}
pub fn is_string(&self) -> bool {
self.as_str().is_some()
}
pub fn as_str(&self) -> Option<&str> {
match *self {
RefValue::String(ref s) => Some(s),
_ => None,
}
}
pub fn is_number(&self) -> bool {
match *self {
RefValue::Number(_) => true,
_ => false,
}
}
pub fn as_number(&self) -> Option<Number> {
match *self {
RefValue::Number(ref n) => Some(n.clone()),
_ => None,
}
}
pub fn is_boolean(&self) -> bool {
self.as_bool().is_some()
}
pub fn as_bool(&self) -> Option<bool> {
match *self {
RefValue::Bool(b) => Some(b),
_ => None,
}
}
pub fn is_null(&self) -> bool {
self.as_null().is_some()
}
pub fn as_null(&self) -> Option<()> {
match *self {
RefValue::Null => Some(()),
_ => None,
}
}
}
impl Into<RefValueWrapper> for RefValue {
fn into(self) -> RefValueWrapper {
let wrap = RefValueWrapper::wrap(self);
RefValueWrapper::new(wrap)
}
}
struct RefValueConverter;
impl RefValueConverter {
fn new(value: &Value) -> TypeRefValue {
RefValueConverter {}.visit_value(value)
}
fn visit_value(&self, value: &Value) -> TypeRefValue {
match value {
Value::Null => self.visit_null(),
Value::Bool(v) => self.visit_bool(v),
Value::Number(v) => self.visit_number(v),
Value::String(v) => self.visit_string(v),
Value::Array(v) => self.visit_array(v),
Value::Object(v) => self.visit_object(v),
}
}
fn visit_null(&self) -> TypeRefValue {
RefValueWrapper::wrap(RefValue::Null)
}
fn visit_bool(&self, value: &bool) -> TypeRefValue {
RefValueWrapper::wrap(RefValue::Bool(*value))
}
fn visit_number(&self, value: &serde_json::Number) -> TypeRefValue {
RefValueWrapper::wrap(RefValue::Number(value.clone()))
}
fn visit_string(&self, value: &String) -> TypeRefValue {
RefValueWrapper::wrap(RefValue::String(value.to_string()))
}
fn visit_array(&self, value: &Vec<Value>) -> TypeRefValue {
let mut values = Vec::new();
for v in value {
values.push(self.visit_value(v));
}
RefValueWrapper::wrap(RefValue::Array(values))
}
fn visit_object(&self, value: &serde_json::Map<String, Value>) -> TypeRefValue {
let mut map = IndexMap::new();
let keys: Vec<String> = value.keys().into_iter().map(|k| k.to_string()).collect();
for k in keys {
let value = self.visit_value(match value.get(&k) {
Some(v) => v,
_ => &Value::Null
});
map.insert(k, value);
}
RefValueWrapper::wrap(RefValue::Object(map))
}
}
struct ValueConverter;
impl ValueConverter {
fn new(value: &TypeRefValue) -> Value {
ValueConverter {}.visit_value(value)
}
fn visit_value(&self, value: &TypeRefValue) -> Value {
match &***value {
RefValue::Null => self.visit_null(),
RefValue::Bool(v) => self.visit_bool(v),
RefValue::Number(v) => self.visit_number(v),
RefValue::String(v) => self.visit_string(v),
RefValue::Array(v) => self.visit_array(v),
RefValue::Object(v) => self.visit_object(v),
}
}
fn visit_null(&self) -> Value {
Value::Null
}
fn visit_bool(&self, value: &bool) -> Value {
Value::Bool(*value)
}
fn visit_number(&self, value: &serde_json::Number) -> Value {
Value::Number(value.clone())
}
fn visit_string(&self, value: &String) -> Value {
Value::String(value.clone())
}
fn visit_array(&self, value: &Vec<TypeRefValue>) -> Value {
let mut values = Vec::new();
for v in value {
values.push(self.visit_value(v));
}
Value::Array(values)
}
fn visit_object(&self, map: &IndexMap<String, TypeRefValue>) -> Value {
let mut ret = serde_json::Map::new();
let keys: Vec<String> = map.keys().into_iter().map(|k: &String| k.to_string()).collect();
let tmp_null = &RefValueWrapper::wrap(RefValue::Null);
for k in keys {
let value = self.visit_value(match map.get(&k) {
Some(e) => e,
_ => tmp_null
});
ret.insert(k, value);
}
Value::Object(ret)
}
}
pub mod model;
mod convert;
pub mod de;
pub mod ser;
//mod utf8;

257
src/ref_value/model.rs Normal file
View File

@ -0,0 +1,257 @@
use std::hash::{Hash, Hasher};
use std::ops::Deref;
use std::sync::Arc;
use indexmap::map::IndexMap;
use serde_json::{Number, Value};
use super::convert::*;
type TypeRefValue = Arc<Box<RefValue>>;
#[derive(Debug, PartialEq)]
pub struct RefValueWrapper {
data: TypeRefValue
}
impl Eq for RefValueWrapper {}
impl Deref for RefValueWrapper {
type Target = RefValue;
fn deref(&self) -> &Self::Target {
&(**self.data)
}
}
impl Hash for RefValueWrapper {
fn hash<H: Hasher>(&self, state: &mut H) {
self.deref().hash(state)
}
}
impl Clone for RefValueWrapper {
fn clone(&self) -> Self {
RefValueWrapper {
data: self.data.clone()
}
}
}
///
/// serde_json::Value 참고
///
pub trait RefIndex {
fn index_into<'v>(&self, v: &'v RefValue) -> Option<&'v RefValueWrapper>;
fn index_into_mut<'v>(&self, v: &'v mut RefValue) -> Option<&'v mut RefValueWrapper>;
fn index_or_insert<'v>(&self, v: &'v mut RefValue) -> &'v mut RefValueWrapper;
}
impl RefIndex for usize {
fn index_into<'v>(&self, v: &'v RefValue) -> Option<&'v RefValueWrapper> {
match *v {
RefValue::Array(ref vec) => vec.get(*self),
_ => None,
}
}
fn index_into_mut<'v>(&self, v: &'v mut RefValue) -> Option<&'v mut RefValueWrapper> {
match *v {
RefValue::Array(ref mut vec) => vec.get_mut(*self),
_ => None,
}
}
fn index_or_insert<'v>(&self, v: &'v mut RefValue) -> &'v mut RefValueWrapper {
match *v {
RefValue::Array(ref mut vec) => {
let len = vec.len();
vec.get_mut(*self).unwrap_or_else(|| {
panic!(
"cannot access index {} of JSON array of length {}",
self, len
)
})
}
_ => panic!("cannot access index {} of JSON {:?}", self, v),
}
}
}
impl RefIndex for str {
fn index_into<'v>(&self, v: &'v RefValue) -> Option<&'v RefValueWrapper> {
match *v {
RefValue::Object(ref map) => map.get(self),
_ => None,
}
}
fn index_into_mut<'v>(&self, v: &'v mut RefValue) -> Option<&'v mut RefValueWrapper> {
match *v {
RefValue::Object(ref mut map) => map.get_mut(self),
_ => None,
}
}
fn index_or_insert<'v>(&self, v: &'v mut RefValue) -> &'v mut RefValueWrapper {
if let RefValue::Null = *v {
*v = RefValue::Object(IndexMap::new());
}
match *v {
RefValue::Object(ref mut map) => {
map.entry(self.to_owned()).or_insert(RefValue::Null.into())
}
_ => panic!("cannot access key {:?} in JSON {:?}", self, v),
}
}
}
impl RefIndex for String {
fn index_into<'v>(&self, v: &'v RefValue) -> Option<&'v RefValueWrapper> {
self[..].index_into(v)
}
fn index_into_mut<'v>(&self, v: &'v mut RefValue) -> Option<&'v mut RefValueWrapper> {
self[..].index_into_mut(v)
}
fn index_or_insert<'v>(&self, v: &'v mut RefValue) -> &'v mut RefValueWrapper {
self[..].index_or_insert(v)
}
}
#[derive(Debug, PartialEq)]
pub enum RefValue {
Null,
Bool(bool),
Number(Number),
String(String),
Array(Vec<RefValueWrapper>),
Object(IndexMap<String, RefValueWrapper>),
}
impl Hash for RefValue {
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
RefValue::Null => RefValue::Null.hash(state),
RefValue::Bool(b) => b.hash(state),
RefValue::Number(n) => {
if n.is_f64() {
n.as_f64().unwrap().to_string().hash(state)
} else if n.is_i64() {
n.as_i64().unwrap().hash(state);
} else {
n.as_u64().unwrap().hash(state);
}
}
RefValue::String(s) => s.hash(state),
RefValue::Object(map) => {
for (_, v) in map {
v.hash(state);
}
}
RefValue::Array(v) => {
for i in v {
i.hash(state);
}
}
}
}
}
impl Eq for RefValue {}
impl RefValue {
pub fn get<I: RefIndex>(&self, index: I) -> Option<&RefValueWrapper> {
index.index_into(self)
}
pub fn is_object(&self) -> bool {
self.as_object().is_some()
}
pub fn as_object(&self) -> Option<&IndexMap<String, RefValueWrapper>> {
match *self {
RefValue::Object(ref map) => Some(map),
_ => None,
}
}
pub fn is_array(&self) -> bool {
self.as_array().is_some()
}
pub fn as_array(&self) -> Option<&Vec<RefValueWrapper>> {
match *self {
RefValue::Array(ref array) => Some(&*array),
_ => None,
}
}
pub fn is_string(&self) -> bool {
self.as_str().is_some()
}
pub fn as_str(&self) -> Option<&str> {
match *self {
RefValue::String(ref s) => Some(s),
_ => None,
}
}
pub fn is_number(&self) -> bool {
match *self {
RefValue::Number(_) => true,
_ => false,
}
}
pub fn as_number(&self) -> Option<Number> {
match *self {
RefValue::Number(ref n) => Some(n.clone()),
_ => None,
}
}
pub fn is_boolean(&self) -> bool {
self.as_bool().is_some()
}
pub fn as_bool(&self) -> Option<bool> {
match *self {
RefValue::Bool(b) => Some(b),
_ => None,
}
}
pub fn is_null(&self) -> bool {
self.as_null().is_some()
}
pub fn as_null(&self) -> Option<()> {
match *self {
RefValue::Null => Some(()),
_ => None,
}
}
}
impl Into<RefValueWrapper> for RefValue {
fn into(self) -> RefValueWrapper {
RefValueWrapper {
data: Arc::new(Box::new(self))
}
}
}
impl Into<RefValueWrapper> for &Value {
fn into(self) -> RefValueWrapper {
RefValueConverter::new(&self)
}
}
impl Into<Value> for RefValueWrapper {
fn into(self) -> Value {
ValueConverter::new(&self)
}
}
impl Into<Value> for &RefValueWrapper {
fn into(self) -> Value {
ValueConverter::new(&self)
}
}

63
src/ref_value/ser.rs Normal file
View File

@ -0,0 +1,63 @@
use std::result::Result;
use serde::{self, Serialize};
use ref_value::model::{RefValue, RefValueWrapper};
impl Serialize for RefValue {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where
S: serde::Serializer {
match *self {
RefValue::Null => serializer.serialize_unit(),
RefValue::Bool(b) => serializer.serialize_bool(b),
RefValue::Number(ref n) => n.serialize(serializer),
RefValue::String(ref s) => serializer.serialize_str(s),
RefValue::Array(ref v) => {
use std::ops::Deref;
let v: Vec<&RefValue> = v.iter().map(|v| v.deref()).collect();
v.serialize(serializer)
},
RefValue::Object(ref m) => {
use serde::ser::SerializeMap;
use std::ops::Deref;
let mut map = serializer.serialize_map(Some(m.len()))?;
for (k, v) in m {
map.serialize_key(k)?;
map.serialize_value(v.deref())?;
}
map.end()
}
}
}
}
impl Serialize for RefValueWrapper {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where
S: serde::Serializer {
use std::ops::Deref;
match *self.deref() {
RefValue::Null => serializer.serialize_unit(),
RefValue::Bool(b) => serializer.serialize_bool(b),
RefValue::Number(ref n) => n.serialize(serializer),
RefValue::String(ref s) => serializer.serialize_str(s),
RefValue::Array(ref v) => {
use std::ops::Deref;
let v: Vec<&RefValue> = v.iter().map(|v| v.deref()).collect();
v.serialize(serializer)
},
RefValue::Object(ref m) => {
use serde::ser::SerializeMap;
use std::ops::Deref;
let mut map = serializer.serialize_map(Some(m.len()))?;
for (k, v) in m {
map.serialize_key(k)?;
map.serialize_value(v.deref())?;
}
map.end()
}
}
}
}

52
src/ref_value/utf8.rs Normal file
View File

@ -0,0 +1,52 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
const TAG_CONT: u8 = 0b1000_0000;
const TAG_TWO_B: u8 = 0b1100_0000;
const TAG_THREE_B: u8 = 0b1110_0000;
const TAG_FOUR_B: u8 = 0b1111_0000;
const MAX_ONE_B: u32 = 0x80;
const MAX_TWO_B: u32 = 0x800;
const MAX_THREE_B: u32 = 0x10000;
#[inline]
pub fn encode(c: char) -> Encode {
let code = c as u32;
let mut buf = [0; 4];
let pos = if code < MAX_ONE_B {
buf[3] = code as u8;
3
} else if code < MAX_TWO_B {
buf[2] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
buf[3] = (code & 0x3F) as u8 | TAG_CONT;
2
} else if code < MAX_THREE_B {
buf[1] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT;
buf[3] = (code & 0x3F) as u8 | TAG_CONT;
1
} else {
buf[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
buf[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT;
buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT;
buf[3] = (code & 0x3F) as u8 | TAG_CONT;
0
};
Encode { buf: buf, pos: pos }
}
pub struct Encode {
buf: [u8; 4],
pos: usize,
}
impl Encode {
pub fn as_str(&self) -> &str {
std::str::from_utf8(&self.buf[self.pos..]).unwrap()
}
}

View File

@ -64,7 +64,8 @@ fn step_in() {
"Vincent Cannon",
"Gray Berry"
]);
assert_eq!(friends, current.get_val().into_value());
assert_eq!(friends, current.into_value());
}
let mut jf = new_value_filter("./benches/data_obj.json");
{
@ -77,7 +78,7 @@ fn step_in() {
"Vincent Cannon",
"Gray Berry"
]);
assert_eq!(names, current.get_val().into_value());
assert_eq!(names, current.into_value());
}
}
@ -91,32 +92,32 @@ fn array() {
]);
let jf = do_filter("$.school.friends[1, 2]", "./benches/data_obj.json");
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$.school.friends[1:]", "./benches/data_obj.json");
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$.school.friends[:-2]", "./benches/data_obj.json");
let friends = json!([
{"id": 0, "name": "Millicent Norman"}
]);
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$..friends[2].name", "./benches/data_obj.json");
let friends = json!(["Gray Berry", "Gray Berry"]);
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$..friends[*].name", "./benches/data_obj.json");
let friends = json!(["Vincent Cannon","Gray Berry","Millicent Norman","Vincent Cannon","Gray Berry"]);
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$['school']['friends'][*].['name']", "./benches/data_obj.json");
let friends = json!(["Millicent Norman","Vincent Cannon","Gray Berry"]);
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$['school']['friends'][0].['name']", "./benches/data_obj.json");
let friends = json!("Millicent Norman");
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
}
#[test]
@ -132,16 +133,16 @@ fn return_type() {
});
let jf = do_filter("$.school", "./benches/data_obj.json");
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$.school[?(@.friends[0])]", "./benches/data_obj.json");
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$.school[?(@.friends[10])]", "./benches/data_obj.json");
assert_eq!(Value::Null, jf.current_value().into_value());
assert_eq!(Value::Null, jf.into_value());
let jf = do_filter("$.school[?(1==1)]", "./benches/data_obj.json");
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$.school.friends[?(1==1)]", "./benches/data_obj.json");
let friends = json!([
@ -149,7 +150,7 @@ fn return_type() {
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]);
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
}
#[test]
@ -164,42 +165,42 @@ fn op() {
{"id": 2, "name": "Gray Berry"}
]
});
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$.friends[?(@.name)]", "./benches/data_obj.json");
let friends = json!([
{ "id" : 1, "name" : "Vincent Cannon" },
{ "id" : 2, "name" : "Gray Berry" }
]);
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$.friends[?(@.id >= 2)]", "./benches/data_obj.json");
let friends = json!([
{ "id" : 2, "name" : "Gray Berry" }
]);
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$.friends[?(@.id >= 2 || @.id == 1)]", "./benches/data_obj.json");
let friends = json!([
{ "id" : 2, "name" : "Gray Berry" },
{ "id" : 1, "name" : "Vincent Cannon" }
]);
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$.friends[?( (@.id >= 2 || @.id == 1) && @.id == 0)]", "./benches/data_obj.json");
assert_eq!(Value::Null, jf.current_value().into_value());
assert_eq!(Value::Null, jf.into_value());
let jf = do_filter("$..friends[?(@.id == $.index)].id", "./benches/data_obj.json");
let friends = json!([0, 0]);
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$..book[?($.store.bicycle.price < @.price)].price", "./benches/example.json");
let friends = json!([22.99]);
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
let jf = do_filter("$..book[?( (@.price == 12.99 || @.category == 'reference') && @.price > 10)].price", "./benches/example.json");
let friends = json!([12.99]);
assert_eq!(friends, jf.current_value().into_value());
assert_eq!(friends, jf.into_value());
}
#[test]
@ -208,10 +209,10 @@ fn example() {
let jf = do_filter("$.store.book[*].author", "./benches/example.json");
let ret = json!(["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]);
assert_eq!(ret, jf.current_value().into_value());
assert_eq!(ret, jf.into_value());
let jf = do_filter("$..author", "./benches/example.json");
assert_eq!(ret, jf.current_value().into_value());
assert_eq!(ret, jf.into_value());
let jf = do_filter("$.store.*", "./benches/example.json");
let ret = json!([
@ -223,11 +224,11 @@ fn example() {
],
{"color" : "red","price" : 19.95},
]);
assert_eq!(ret, jf.current_value().into_value());
assert_eq!(ret, jf.into_value());
let jf = do_filter("$.store..price", "./benches/example.json");
let ret = json!([8.95, 12.99, 8.99, 22.99, 19.95]);
assert_eq!(ret, jf.current_value().into_value());
assert_eq!(ret, jf.into_value());
let jf = do_filter("$..book[2]", "./benches/example.json");
let ret = json!([{
@ -237,7 +238,7 @@ fn example() {
"isbn" : "0-553-21311-3",
"price" : 8.99
}]);
assert_eq!(ret, jf.current_value().into_value());
assert_eq!(ret, jf.into_value());
let jf = do_filter("$..book[-2]", "./benches/example.json");
let ret = json!([{
@ -247,7 +248,7 @@ fn example() {
"isbn" : "0-553-21311-3",
"price" : 8.99
}]);
assert_eq!(ret, jf.current_value().into_value());
assert_eq!(ret, jf.into_value());
let jf = do_filter("$..book[0,1]", "./benches/example.json");
let ret = json!([
@ -264,7 +265,7 @@ fn example() {
"price" : 12.99
}
]);
assert_eq!(ret, jf.current_value().into_value());
assert_eq!(ret, jf.into_value());
let jf = do_filter("$..book[:2]", "./benches/example.json");
let ret = json!([
@ -281,7 +282,7 @@ fn example() {
"price" : 12.99
}
]);
assert_eq!(ret, jf.current_value().into_value());
assert_eq!(ret, jf.into_value());
let jf = do_filter("$..book[2:]", "./benches/example.json");
let ret = json!([
@ -300,7 +301,7 @@ fn example() {
"price" : 22.99
}
]);
assert_eq!(ret, jf.current_value().into_value());
assert_eq!(ret, jf.into_value());
let jf = do_filter("$..book[?(@.isbn)]", "./benches/example.json");
let ret = json!([
@ -319,7 +320,7 @@ fn example() {
"price" : 22.99
}
]);
assert_eq!(ret, jf.current_value().into_value());
assert_eq!(ret, jf.into_value());
let jf = do_filter("$.store.book[?(@.price < 10)]", "./benches/example.json");
let ret = json!([
@ -337,9 +338,9 @@ fn example() {
"price" : 8.99
}
]);
assert_eq!(ret, jf.current_value().into_value());
assert_eq!(ret, jf.into_value());
let jf = do_filter("$..*", "./benches/example.json");
let json: Value = serde_json::from_str(read_json("./benches/giveme_every_thing_result.json").as_str()).unwrap();
assert_eq!(json, jf.current_value().into_value());
assert_eq!(json, jf.into_value());
}

View File

@ -15,6 +15,13 @@ fn read_json(path: &str) -> Value {
serde_json::from_str(contents.as_str()).unwrap()
}
fn read_contents(path: &str) -> String {
let mut f = std::fs::File::open(path).unwrap();
let mut contents = String::new();
f.read_to_string(&mut contents).unwrap();
contents
}
#[test]
fn compile() {
let mut template = jsonpath::compile("$..friends[2]");
@ -67,3 +74,18 @@ fn select() {
}]);
assert_eq!(json, ret);
}
#[test]
fn select_str() {
let json_str = read_contents("./benches/example.json");
let result_str = jsonpath::select_str(&json_str, "$..book[2]").unwrap();
let ret = json!([{
"category" : "fiction",
"author" : "Herman Melville",
"title" : "Moby Dick",
"isbn" : "0-553-21311-3",
"price" : 8.99
}]);
let json: Value = serde_json::from_str(&result_str).unwrap();
assert_eq!(json, ret);
}

39
tests/serde.rs Normal file
View File

@ -0,0 +1,39 @@
extern crate jsonpath_lib as jsonpath;
extern crate serde_json;
use std::io::Read;
use serde_json::Value;
use jsonpath::prelude::*;
fn read_json(path: &str) -> String {
let mut f = std::fs::File::open(path).unwrap();
let mut contents = String::new();
f.read_to_string(&mut contents).unwrap();
contents
}
#[test]
fn de() {
let json_str = read_json("./benches/example.json");
// RefValue -> Value
let ref_value: RefValue = serde_json::from_str(json_str.as_str()).unwrap();
let value_wrapper: RefValueWrapper = ref_value.into();
let value: Value = value_wrapper.into();
// Value
let json: Value = serde_json::from_str(json_str.as_str()).unwrap();
assert_eq!(value, json);
}
#[test]
fn ser() {
let json_str = read_json("./benches/example.json");
let ref_value: RefValue = serde_json::from_str(json_str.as_str()).unwrap();
let ref_value_str = serde_json::to_string(&ref_value).unwrap();
let json: Value = serde_json::from_str(json_str.as_str()).unwrap();
let json_str = serde_json::to_string(&json).unwrap();
assert_eq!(ref_value_str, json_str);
}

View File

@ -1,6 +1,6 @@
[package]
name = "jsonpath-wasm"
version = "0.1.4"
version = "0.1.5"
authors = ["Changseok Han <freestrings@gmail.com>"]
description = "JsonPath Webassembly version compiled by Rust - Demo: https://freestrings.github.io/jsonpath"
keywords = ["library", "jsonpath", "json", "webassembly"]

View File

@ -29,14 +29,14 @@ cfg_if! {
fn filter_ref_value(json: RefValueWrapper, node: Node) -> JsValue {
let mut jf = JsonValueFilter::new_from_value(json);
jf.visit(node);
let taken = jf.take_value().into_value();
let taken: Value = jf.take_value().into();
match JsValue::from_serde(&taken) {
Ok(js_value) => js_value,
Err(e) => JsValue::from_str(&format!("Json deserialize error: {:?}", e))
}
}
fn into_serde_json(js_value: &JsValue) -> Result<Value, String> {
fn into_serde_json(js_value: &JsValue) -> Result<RefValue, String> {
if js_value.is_string() {
match serde_json::from_str(js_value.as_string().unwrap().as_str()) {
Ok(json) => Ok(json),
@ -52,7 +52,7 @@ fn into_serde_json(js_value: &JsValue) -> Result<Value, String> {
fn into_ref_value(js_value: &JsValue, node: Node) -> JsValue {
match into_serde_json(js_value) {
Ok(json) => filter_ref_value((&json).into(), node),
Ok(json) => filter_ref_value(json.into(), node),
Err(e) => JsValue::from_str(&format!("Json serialize error: {}", e))
}
}
@ -85,7 +85,7 @@ pub fn alloc_json(js_value: JsValue) -> usize {
let mut idx = CACHE_JSON_IDX.lock().unwrap();
*idx += 1;
map.insert(*idx, (&json).into());
map.insert(*idx, json.into());
*idx
}
Err(e) => {
@ -136,7 +136,7 @@ pub fn selector(js_value: JsValue) -> JsValue {
}
_ => {
match into_serde_json(&js_value) {
Ok(json) => (&json).into(),
Ok(json) => json.into(),
Err(e) => return JsValue::from_str(e.as_str())
}
}