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..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,31 +1027,29 @@ 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 { - let v = if let Some(v) = map.get(token) { - fun(v) - } else { - return; - }; - - map.insert(token.clone(), 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::() { 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 +1173,7 @@ impl SelectorMut { } } - pub fn replace_with Value>( + pub fn replace_with Value>( &mut self, fun: &mut F, ) -> Result<&mut Self, JsonPathError> { 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,