diff --git a/src/filter/term.rs b/src/filter/term.rs index 8c25979..8a1571f 100644 --- a/src/filter/term.rs +++ b/src/filter/term.rs @@ -35,12 +35,12 @@ impl TermContext { } } - let mut c = v.into_term(key); - let mut oc = ov.into_term(key_other); + let c = v.into_term(key); + let oc = ov.into_term(key_other); if is_json(&c) && is_json(&oc) { v.cmp(&ov, cmp_fn.into_type()) } else { - c.cmp(&mut oc, cmp_fn, default) + c.cmp(&oc, cmp_fn, default) } } TermContext::Constants(et) => { diff --git a/src/filter/value_filter.rs b/src/filter/value_filter.rs index 542f519..445de39 100644 --- a/src/filter/value_filter.rs +++ b/src/filter/value_filter.rs @@ -54,6 +54,73 @@ pub enum ValueFilterKey { All, } +fn iter_to_value_vec<'a, I: Iterator>(iter: I) -> Vec { + iter + .map(|v| v.clone()) + .filter(|v| !v.is_null()) + .collect() +} + +fn get_nested_array(v: &RefValueWrapper, key: F, filter_mode: bool) -> RefValueWrapper { + if v.is_array() && v.as_array().unwrap().get(key.index(v)).is_some() { + if filter_mode { + v.clone() + } else { + let idx = key.index(v); + v.get(idx).unwrap().clone() + } + } else { + key.take_value(v) + } +} + +fn get_nested_object(v: &RefValueWrapper, key: &String, filter_mode: bool) -> RefValueWrapper { + if v.is_object() && v.as_object().unwrap().contains_key(key) { + if filter_mode { + v.clone() + } else { + v.get(key.clone()).unwrap().clone() + } + } else { + RefValue::Null.into() + } +} + +fn traverse(key: Option<&String>, v: &RefValueWrapper, buf: &mut Vec) { + match v.deref() { + RefValue::Array(vec) => { + if key.is_none() { + for v in vec { + buf.push(v.clone()); + } + } + for i in vec { + traverse(key, i, buf); + } + } + RefValue::Object(v) => { + for (k, v) in v.into_iter() { + if match key { + Some(map_key) => map_key == k, + _ => true + } { + buf.push(v.clone()); + } + } + for (_, v) in v.into_iter() { + traverse(key, v, buf); + } + } + _ => {} + } +} + +fn collect_all(key: Option<&String>, v: &RefValueWrapper) -> Vec { + let mut buf = Vec::new(); + traverse(key, v, &mut buf); + buf +} + #[derive(Debug)] pub struct ValueFilter { val_wrapper: ValueWrapper, @@ -66,74 +133,16 @@ impl ValueFilter { ValueFilter { val_wrapper: ValueWrapper::new(v, is_leaves), last_key: None, filter_mode } } - fn iter_to_value_vec<'a, I: Iterator>(iter: I) -> Vec { - iter - .map(|v| v.clone()) - .filter(|v| !v.is_null()) - .collect() - } - - fn get_nested_array(v: &RefValueWrapper, key: F, filter_mode: bool) -> RefValueWrapper { - if v.is_array() && v.as_array().unwrap().get(key.index(v)).is_some() { - if filter_mode { - v.clone() - } else { - let idx = key.index(v); - v.get(idx).unwrap().clone() - } - } else { - key.take_value(v) - } - } - - fn get_nested_object(v: &RefValueWrapper, key: &String, filter_mode: bool) -> RefValueWrapper { - if v.is_object() && v.as_object().unwrap().contains_key(key) { - if filter_mode { - v.clone() - } else { - v.get(key.clone()).unwrap().clone() - } - } else { - RefValue::Null.into() - } - } - - fn collect_all(key: Option<&String>, v: &RefValueWrapper, buf: &mut Vec) { - match v.deref() { - RefValue::Array(vec) => { - if key.is_none() { - for v in vec { - buf.push(v.clone()); - } - } - for i in vec { - Self::collect_all(key, i, buf); - } - } - RefValue::Object(v) => { - for (k, v) in v.into_iter() { - if match key { - Some(map_key) => map_key == k, - _ => true - } { - buf.push(v.clone()); - } - } - for (_, v) in v.into_iter() { - Self::collect_all(key, v, buf); - } - } - _ => {} - } + fn step_leaves(&mut self, key: Option<&String>) { + let buf = collect_all(key, &self.val_wrapper.get_val()); + trace!("step_leaves - {:?}", buf); + self.val_wrapper = ValueWrapper::new(RefValue::Array(buf).into(), true); } pub fn step_leaves_all(&mut self) -> &ValueWrapper { debug!("step_leaves_all"); - let mut buf = Vec::new(); - Self::collect_all(None, &self.val_wrapper.get_val(), &mut buf); - trace!("step_leaves_all - {:?}", buf); + self.step_leaves(None); self.last_key = Some(ValueFilterKey::All); - self.val_wrapper = ValueWrapper::new(RefValue::Array(buf).into(), true); &self.val_wrapper } @@ -143,11 +152,8 @@ impl ValueFilter { pub fn step_leaves_string(&mut self, key: &String) -> &ValueWrapper { debug!("step_leaves_string"); - let mut buf = Vec::new(); - Self::collect_all(Some(key), &self.val_wrapper.get_val(), &mut buf); - trace!("step_leaves_string - {:?}", buf); + self.step_leaves(Some(key)); self.last_key = Some(ValueFilterKey::String(key.clone())); - self.val_wrapper = ValueWrapper::new(RefValue::Array(buf).into(), true); &self.val_wrapper } @@ -156,10 +162,10 @@ impl ValueFilter { let vec = match self.val_wrapper.get_val().deref() { RefValue::Object(ref map) => { - Self::iter_to_value_vec(map.values()) + iter_to_value_vec(map.values()) } RefValue::Array(ref list) => { - Self::iter_to_value_vec(list.iter()) + iter_to_value_vec(list.iter()) } RefValue::Null => Vec::new(), _ => vec![self.val_wrapper.get_val().clone()] @@ -184,7 +190,7 @@ impl ValueFilter { RefValue::Array(ref vec) => { let mut ret = Vec::new(); for v in vec { - let wrapper = Self::get_nested_array(v, *key, filter_mode); + let wrapper = get_nested_array(v, *key, filter_mode); if !wrapper.is_null() { ret.push(wrapper.clone()); } @@ -219,19 +225,19 @@ impl ValueFilter { let val = match self.val_wrapper.get_val().deref() { RefValue::Array(ref vec) if is_leaves => { let mut buf = Vec::new(); - for mut v in vec { + for v in vec { 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, key, filter_mode); + let nested_wrapper = get_nested_object(v, key, filter_mode); if !nested_wrapper.is_null() { ret.push(nested_wrapper.clone()); } } buf.append(&mut ret); } else if v.is_object() { - let nested_wrapper = Self::get_nested_object(v, key, filter_mode); + let nested_wrapper = get_nested_object(v, key, filter_mode); if !nested_wrapper.is_null() { buf.push(nested_wrapper.clone()); } @@ -248,7 +254,7 @@ 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, key, filter_mode); + let wrapper = get_nested_object(v, key, filter_mode); if !wrapper.is_null() { ret.push(wrapper.clone()); } @@ -361,7 +367,7 @@ impl JsonValueFilter { Some(ref mut vf) if vf.val_wrapper.is_array() && vf.val_wrapper.is_leaves() => { let mut ret = Vec::new(); if let RefValue::Array(val) = vf.val_wrapper.get_val().deref() { - for mut v in val { + for v in val { for i in &indices { let v = i.take_value(v); if !v.is_null() { @@ -421,7 +427,7 @@ impl JsonValueFilter { Some(ref mut vf) if vf.val_wrapper.is_array() && vf.val_wrapper.is_leaves() => { let mut buf = Vec::new(); if let RefValue::Array(vec) = vf.val_wrapper.get_val().deref() { - for mut v in vec { + for v in vec { let (from, to) = _from_to(from, to, v); let mut v: Vec = _range(from, to, v); buf.append(&mut v); @@ -495,7 +501,7 @@ impl JsonValueFilter { } _ => { match self.filter_stack.pop() { - Some(mut vf) => { + Some(vf) => { let is_leaves = vf.val_wrapper.is_leaves(); match vf.val_wrapper.get_val().deref() { RefValue::Null | RefValue::Bool(false) => { diff --git a/src/filter/value_wrapper.rs b/src/filter/value_wrapper.rs index 4b5922a..fec9cd1 100644 --- a/src/filter/value_wrapper.rs +++ b/src/filter/value_wrapper.rs @@ -9,6 +9,28 @@ use super::cmp::*; use super::term::*; use super::value_filter::*; +fn cmp_with_term(val: &RefValueWrapper, et: &ExprTerm, cmp_fn: &F, default: bool, reverse: bool) -> bool { + 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) }, + _ => default + } + } + RefValue::Number(ref v1) => match et { + ExprTerm::Number(v2) => if reverse { cmp_fn.cmp_f64(v2, &v1.as_f64().unwrap()) } else { cmp_fn.cmp_f64(&v1.as_f64().unwrap(), v2) }, + _ => default + }, + RefValue::String(ref v1) => { + match et { + ExprTerm::String(v2) => if reverse { cmp_fn.cmp_string(v2, v1) } else { cmp_fn.cmp_string(v1, v2) }, + _ => default + } + } + _ => default + } +} + #[derive(Debug)] pub struct ValueWrapper { val: RefValueWrapper, @@ -42,28 +64,6 @@ impl ValueWrapper { } } - fn cmp_with_term(val: &RefValueWrapper, et: &ExprTerm, cmp_fn: &F, default: bool, reverse: bool) -> bool { - 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) }, - _ => default - } - } - RefValue::Number(ref v1) => match et { - ExprTerm::Number(v2) => if reverse { cmp_fn.cmp_f64(v2, &v1.as_f64().unwrap()) } else { cmp_fn.cmp_f64(&v1.as_f64().unwrap(), v2) }, - _ => default - }, - RefValue::String(ref v1) => { - match et { - ExprTerm::String(v2) => if reverse { cmp_fn.cmp_string(v2, v1) } else { cmp_fn.cmp_string(v1, v2) }, - _ => default - } - } - _ => default - } - } - fn take_object_in_array(&self, key: &String, et: &ExprTerm, cmp: &F, reverse: bool) -> Option { fn _filter_with_object bool>(v: &RefValueWrapper, key: &String, fun: F) -> bool { match v.deref() { @@ -82,7 +82,7 @@ impl ValueWrapper { let mut set = IndexSet::new(); for v in vec { if _filter_with_object(v, key, |vv| { - Self::cmp_with_term(vv, et, cmp, false, reverse) + cmp_with_term(vv, et, cmp, false, reverse) }) { set.insert(v.clone()); } @@ -111,7 +111,7 @@ impl ValueWrapper { RefValue::Array(vec) => { let mut set = IndexSet::new(); for v in vec { - if Self::cmp_with_term(v, et, &cmp, false, reverse) { + if cmp_with_term(v, et, &cmp, false, reverse) { set.insert(v.clone()); } } @@ -119,7 +119,7 @@ impl ValueWrapper { ValueWrapper::new(RefValue::Array(ret).into(), false) } _ => { - if Self::cmp_with_term(&self.val, et, &cmp, false, reverse) { + if cmp_with_term(&self.val, et, &cmp, false, reverse) { ValueWrapper::new(self.val.clone(), false) } else { ValueWrapper::new(RefValue::Null.into(), false) @@ -132,8 +132,8 @@ impl ValueWrapper { pub fn replace(&mut self, val: RefValueWrapper) { 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 }, + RefValue::Array(v) => v.is_empty(), + RefValue::Object(m) => m.is_empty(), _ => val.is_null() }; self.val = if is_null { diff --git a/tests/readme.rs b/tests/readme.rs index 459a736..4243fa5 100644 --- a/tests/readme.rs +++ b/tests/readme.rs @@ -48,7 +48,7 @@ fn readme_selector() { let _ = selector.map(|v| { let r = match v { Value::Array(mut vec) => { - for mut v in &mut vec { + for v in &mut vec { v.as_object_mut().unwrap().remove("age"); } Value::Array(vec) diff --git a/tests/selector.rs b/tests/selector.rs index 19dc07f..464761d 100644 --- a/tests/selector.rs +++ b/tests/selector.rs @@ -107,7 +107,7 @@ fn selector_select_to() { fn _remove_name(v: Value) -> Option { let r = match v { Value::Array(mut vec) => { - for mut v in &mut vec { + for v in &mut vec { v.as_object_mut().unwrap().remove("name"); } Value::Array(vec)