From 8b85ec9d614c76c03e7b61a7e52d0fb19eef2f6c Mon Sep 17 00:00:00 2001 From: Guy Korland Date: Sun, 11 Aug 2019 18:07:15 +0300 Subject: [PATCH 1/3] pass value not reference to fun --- src/lib.rs | 2 +- src/select/mod.rs | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b42d4fb..7ee96da 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -460,7 +460,7 @@ pub fn delete(value: Value, path: &str) -> Result { /// ``` pub fn replace_with(value: Value, path: &str, fun: &mut F) -> Result where - F: FnMut(&Value) -> Value, + F: FnMut(Value) -> Value, { let mut selector = SelectorMut::default(); let value = selector.str_path(path)?.value(value).replace_with(fun)?; diff --git a/src/select/mod.rs b/src/select/mod.rs index b240b11..4f286a4 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -1026,7 +1026,7 @@ pub struct SelectorMut { value: Option, } -fn replace_value Value>(tokens: Vec, value: &mut Value, fun: &mut F) { +fn replace_value Value>(tokens: Vec, value: &mut Value, fun: &mut F) { let mut target = value; for (i, token) in tokens.iter().enumerate() { @@ -1035,13 +1035,9 @@ fn replace_value Value>(tokens: Vec, value: &mut Val let target_opt = match *target_once { Value::Object(ref mut map) => { if is_last { - let v = if let Some(v) = map.get(token) { - fun(v) - } else { - return; - }; - - map.insert(token.clone(), v); + if let Some(v) = map.remove(token) { + map.insert(token.clone(), fun(v)); + } return; } map.get_mut(token) @@ -1049,8 +1045,8 @@ fn replace_value Value>(tokens: Vec, value: &mut Val Value::Array(ref mut vec) => { if let Ok(x) = token.parse::() { if is_last { - let v = { fun(&vec[x]) }; - vec[x] = v; + let v = std::mem::replace(&mut vec[x], Value::Null); + vec[x] = fun(v); return; } vec.get_mut(x) @@ -1174,7 +1170,7 @@ impl SelectorMut { } } - pub fn replace_with Value>( + pub fn replace_with Value>( &mut self, fun: &mut F, ) -> Result<&mut Self, JsonPathError> { From 88e6320cf797feeb606015d5e0a65bcd5f00f01b Mon Sep 17 00:00:00 2001 From: Guy Korland Date: Sun, 11 Aug 2019 18:27:37 +0300 Subject: [PATCH 2/3] improve performance avoid remove & insert to map --- src/select/mod.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/select/mod.rs b/src/select/mod.rs index 4f286a4..cb64270 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -5,6 +5,7 @@ use array_tool::vec::{Intersect, Union}; use serde_json::{Number, Value}; use parser::*; +use serde_json::map::Entry; fn to_f64(n: &Number) -> f64 { if n.is_i64() { @@ -1026,21 +1027,23 @@ pub struct SelectorMut { value: Option, } -fn replace_value Value>(tokens: Vec, value: &mut Value, fun: &mut F) { +fn replace_value Value>(mut tokens: Vec, value: &mut Value, fun: &mut F) { let mut target = value; - for (i, token) in tokens.iter().enumerate() { + let last_index = tokens.len() - 1; + for (i, token) in tokens.drain(..).enumerate() { let target_once = target; - let is_last = i == tokens.len() - 1; + let is_last = i == last_index; let target_opt = match *target_once { Value::Object(ref mut map) => { if is_last { - if let Some(v) = map.remove(token) { - map.insert(token.clone(), fun(v)); + if let Entry::Occupied(mut e) = map.entry(token) { + let v = e.insert(Value::Null); + e.insert(fun(v)); } return; } - map.get_mut(token) + map.get_mut(&token) } Value::Array(ref mut vec) => { if let Ok(x) = token.parse::() { From b2e27b423ae3b43a5f9d2d859c77fb587a27747d Mon Sep 17 00:00:00 2001 From: Guy Korland Date: Wed, 14 Aug 2019 13:08:03 +0300 Subject: [PATCH 3/3] fix wasm build --- wasm/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs index cf0fb7d..85ae631 100644 --- a/wasm/src/lib.rs +++ b/wasm/src/lib.rs @@ -56,8 +56,8 @@ where } } -fn replace_fun(v: &Value, fun: &js_sys::Function) -> Value { - match JsValue::from_serde(v) { +fn replace_fun(v: Value, fun: &js_sys::Function) -> Value { + match JsValue::from_serde(&v) { Ok(js_v) => match fun.call1(&JsValue::NULL, &js_v) { Ok(result) => match into_serde_json(&result) { Ok(json) => json,