summaryrefslogtreecommitdiffstats
path: root/vendor/jsonpath_lib/src/select/value_walker.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/jsonpath_lib/src/select/value_walker.rs')
-rw-r--r--vendor/jsonpath_lib/src/select/value_walker.rs99
1 files changed, 99 insertions, 0 deletions
diff --git a/vendor/jsonpath_lib/src/select/value_walker.rs b/vendor/jsonpath_lib/src/select/value_walker.rs
new file mode 100644
index 000000000..e7b4de0e0
--- /dev/null
+++ b/vendor/jsonpath_lib/src/select/value_walker.rs
@@ -0,0 +1,99 @@
+use serde_json::Value;
+use std::collections::HashSet;
+
+pub(super) struct ValueWalker;
+
+impl<'a> ValueWalker {
+ pub fn all_with_num(vec: &[&'a Value], tmp: &mut Vec<&'a Value>, index: f64) {
+ Self::walk(vec, tmp, &|v| if v.is_array() {
+ if let Some(item) = v.get(index as usize) {
+ Some(vec![item])
+ } else {
+ None
+ }
+ } else {
+ None
+ });
+ }
+
+ pub fn all_with_str(vec: &[&'a Value], tmp: &mut Vec<&'a Value>, key: &str, is_filter: bool) {
+ if is_filter {
+ Self::walk(vec, tmp, &|v| match v {
+ Value::Object(map) if map.contains_key(key) => Some(vec![v]),
+ _ => None,
+ });
+ } else {
+ Self::walk(vec, tmp, &|v| match v {
+ Value::Object(map) => match map.get(key) {
+ Some(v) => Some(vec![v]),
+ _ => None,
+ },
+ _ => None,
+ });
+ }
+ }
+
+ pub fn all(vec: &[&'a Value], tmp: &mut Vec<&'a Value>) {
+ Self::walk(vec, tmp, &|v| match v {
+ Value::Array(vec) => Some(vec.iter().collect()),
+ Value::Object(map) => {
+ let mut tmp = Vec::new();
+ for (_, v) in map {
+ tmp.push(v);
+ }
+ Some(tmp)
+ }
+ _ => None,
+ });
+ }
+
+ fn walk<F>(vec: &[&'a Value], tmp: &mut Vec<&'a Value>, fun: &F) where F: Fn(&Value) -> Option<Vec<&Value>> {
+ for v in vec {
+ Self::_walk(v, tmp, fun);
+ }
+ }
+
+ fn _walk<F>(v: &'a Value, tmp: &mut Vec<&'a Value>, fun: &F) where F: Fn(&Value) -> Option<Vec<&Value>> {
+ if let Some(mut ret) = fun(v) {
+ tmp.append(&mut ret);
+ }
+
+ match v {
+ Value::Array(vec) => {
+ for v in vec {
+ Self::_walk(v, tmp, fun);
+ }
+ }
+ Value::Object(map) => {
+ for (_, v) in map {
+ Self::_walk(&v, tmp, fun);
+ }
+ }
+ _ => {}
+ }
+ }
+
+ pub fn walk_dedup(v: &'a Value,
+ tmp: &mut Vec<&'a Value>,
+ key: &str,
+ visited: &mut HashSet<*const Value>, ) {
+ match v {
+ Value::Object(map) => {
+ if map.contains_key(key) {
+ let ptr = v as *const Value;
+ if !visited.contains(&ptr) {
+ visited.insert(ptr);
+ tmp.push(v)
+ }
+ }
+ }
+ Value::Array(vec) => {
+ for v in vec {
+ Self::walk_dedup(v, tmp, key, visited);
+ }
+ }
+ _ => {}
+ }
+ }
+}
+