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::() {