Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace fun input with ownership #22

Closed
wants to merge 15 commits into from
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ let result = selector_mut
0
};

json!(age)
Some(json!(age))
}).unwrap()
.take().unwrap();

Expand Down Expand Up @@ -353,7 +353,7 @@ let ret = jsonpath::replace_with(json_obj, "$..[?(@.age == 20)].age", &mut |v| {
0
};

json!(age)
Some(json!(age))
}).unwrap();

assert_eq!(ret, json!({
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ pub fn delete(value: Value, path: &str) -> Result<Value, JsonPathError> {
/// 0
/// };
///
/// json!(age)
/// Some(json!(age))
/// }).unwrap();
///
/// assert_eq!(ret, json!({
Expand All @@ -460,7 +460,7 @@ pub fn delete(value: Value, path: &str) -> Result<Value, JsonPathError> {
/// ```
pub fn replace_with<F>(value: Value, path: &str, fun: &mut F) -> Result<Value, JsonPathError>
where
F: FnMut(Value) -> Value,
F: FnMut(Value) -> Option<Value>,
{
let mut selector = SelectorMut::default();
let value = selector.str_path(path)?.value(value).replace_with(fun)?;
Expand Down
22 changes: 17 additions & 5 deletions src/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,7 @@ pub struct SelectorMut {
value: Option<Value>,
}

fn replace_value<F: FnMut(Value) -> Value>(mut tokens: Vec<String>, value: &mut Value, fun: &mut F) {
fn replace_value<F: FnMut(Value) -> Option<Value>>(mut tokens: Vec<String>, value: &mut Value, fun: &mut F) {
let mut target = value;

let last_index = tokens.len() - 1;
Expand All @@ -1039,7 +1039,11 @@ fn replace_value<F: FnMut(Value) -> Value>(mut tokens: Vec<String>, value: &mut
if is_last {
if let Entry::Occupied(mut e) = map.entry(token) {
let v = e.insert(Value::Null);
e.insert(fun(v));
if let Some(res) = fun(v) {
e.insert(res);
} else {
e.remove();
}
}
return;
}
Expand All @@ -1049,7 +1053,11 @@ fn replace_value<F: FnMut(Value) -> Value>(mut tokens: Vec<String>, value: &mut
if let Ok(x) = token.parse::<usize>() {
if is_last {
let v = std::mem::replace(&mut vec[x], Value::Null);
vec[x] = fun(v);
if let Some(res) = fun(v) {
vec[x] = res;
} else {
vec.remove(x);
}
return;
}
vec.get_mut(x)
Expand Down Expand Up @@ -1155,7 +1163,11 @@ impl SelectorMut {
}

pub fn delete(&mut self) -> Result<&mut Self, JsonPathError> {
self.replace_with(&mut |_| Value::Null)
self.replace_with(&mut |_| Some(Value::Null))
}

pub fn remove(&mut self) -> Result<&mut Self, JsonPathError> {
self.replace_with(&mut |_| None)
}

fn select(&self) -> Result<Vec<&Value>, JsonPathError> {
Expand All @@ -1173,7 +1185,7 @@ impl SelectorMut {
}
}

pub fn replace_with<F: FnMut(Value) -> Value>(
pub fn replace_with<F: FnMut(Value) -> Option<Value>>(
&mut self,
fun: &mut F,
) -> Result<&mut Self, JsonPathError> {
Expand Down
4 changes: 2 additions & 2 deletions tests/readme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ fn readme_selector_mut() {
0
};

json!(age)
Some(json!(age))
})
.unwrap()
.take()
Expand Down Expand Up @@ -522,7 +522,7 @@ fn readme_replace_with() {
0
};

json!(age)
Some(json!(age))
})
.unwrap();

Expand Down
36 changes: 35 additions & 1 deletion tests/selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fn selector_mut() {
if let Value::Number(n) = v {
nums.push(n.as_f64().unwrap());
}
Value::String("a".to_string())
Some(Value::String("a".to_string()))
})
.unwrap()
.take()
Expand Down Expand Up @@ -96,3 +96,37 @@ fn selector_delete() {
]
);
}

#[test]
fn selector_remove() {
setup();

let mut selector_mut = SelectorMut::default();

let result = selector_mut
.str_path(r#"$.store..price[?(@>13)]"#)
.unwrap()
.value(read_json("./benchmark/example.json"))
.remove()
.unwrap()
.take()
.unwrap();

let mut selector = Selector::default();
let result = selector
.str_path(r#"$.store..price"#)
.unwrap()
.value(&result)
.select()
.unwrap();

assert_eq!(
result,
vec![
&json!(8.95),
&json!(12.99),
&json!(8.99)
]
);
}

10 changes: 5 additions & 5 deletions wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,24 +56,24 @@ where
}
}

fn replace_fun(v: Value, fun: &js_sys::Function) -> Value {
fn replace_fun(v: Value, fun: &js_sys::Function) -> Option<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,
Ok(json) => Some(json),
Err(e) => {
console_error!("replace_with - closure returned a invalid JSON: {:?}", e);
Value::Null
Some(Value::Null)
}
},
Err(e) => {
console_error!("replace_with - fail to call closure: {:?}", e);
Value::Null
Some(Value::Null)
}
},
Err(e) => {
console_error!("replace_with - invalid JSON object: {:?}", e);
Value::Null
Some(Value::Null)
}
}
}
Expand Down