json_position_parser/
tree.rs1use super::types::Range;
2use std::collections::HashMap;
3
4#[derive(Debug)]
5pub enum EntryType {
6 JSONObject(HashMap<String, (usize, usize)>), JSONArray(Vec<usize>),
8 String(String),
9 Int(i64),
10 Float(f64),
11 Bool(bool),
12 Null,
13}
14
15#[derive(Debug)]
16pub struct Entry {
17 pub key: Option<usize>,
18 pub range: Range,
19 pub entry_type: EntryType,
20}
21
22#[derive(Debug)]
23pub struct Key {
24 pub name: String,
25 pub range: Range,
26}
27
28#[derive(Debug)]
29pub struct Tree {
30 pub entries: Vec<Entry>,
31 pub keys: Vec<Key>,
32}
33
34#[derive(Debug, Clone)]
35pub enum PathType<'input> {
36 Object(&'input str),
37 Array(usize),
38 Wildcard,
39 RecursiveWildcard,
40}
41
42impl Tree {
43 fn handle_path(&self, entries: &[&Entry], path: &str) -> Vec<&Entry> {
44 entries
45 .iter()
46 .filter_map(|entry| {
47 if let EntryType::JSONObject(entries) = &entry.entry_type {
48 if let Some((_, value)) = entries.get(path) {
49 return self.entries.get(*value);
50 }
51 }
52 None
53 })
54 .collect()
55 }
56
57 fn handle_array(&self, entries: &[&Entry], pos: usize) -> Vec<&Entry> {
58 entries
59 .iter()
60 .filter_map(|entry| {
61 if let EntryType::JSONArray(entries) = &entry.entry_type {
62 if let Some(value) = entries.get(pos) {
63 return self.entries.get(*value);
64 }
65 }
66 None
67 })
68 .collect()
69 }
70
71 fn handle_wildcard(&self, entries: &[&Entry]) -> Vec<&Entry> {
72 entries
73 .iter()
74 .filter_map(|entry| {
75 if let EntryType::JSONObject(hash) = &entry.entry_type {
76 return Some(
77 hash.iter()
78 .filter_map(|(_, (_, entry))| self.entries.get(*entry))
79 .collect(),
80 );
81 }
82
83 if let EntryType::JSONArray(array) = &entry.entry_type {
84 return Some(
85 array
86 .iter()
87 .filter_map(|entry| self.entries.get(*entry))
88 .collect(),
89 );
90 }
91
92 None
93 })
94 .collect::<Vec<Vec<&Entry>>>()
95 .into_iter()
96 .flatten()
97 .collect::<Vec<&Entry>>()
98 }
99
100 fn handle_recursive_wildcard(&self, entries: &[&Entry]) -> Vec<&Entry> {
101 entries
102 .iter()
103 .filter_map(|entry| {
104 if let EntryType::JSONObject(hash) = &entry.entry_type {
105 let values: Vec<&Entry> = hash
106 .iter()
107 .filter_map(|(_, (_, entry))| self.entries.get(*entry))
108 .collect();
109 let next = self.handle_recursive_wildcard(&values);
110 return Some([&values[..], &next[..]].concat());
111 }
112
113 if let EntryType::JSONArray(array) = &entry.entry_type {
114 let values: Vec<&Entry> = array
115 .iter()
116 .filter_map(|entry| self.entries.get(*entry))
117 .collect();
118 let next = self.handle_recursive_wildcard(&values);
119 return Some([&values[..], &next[..]].concat());
120 }
121
122 None
123 })
124 .collect::<Vec<Vec<&Entry>>>()
125 .into_iter()
126 .flatten()
127 .collect::<Vec<&Entry>>()
128 }
129
130 pub fn value_at(&self, path: &[PathType]) -> Vec<&Entry> {
147 let mut vec = vec![];
148 if let Some(first) = self.entries.last() {
149 vec.push(first);
150 return path.iter().fold(vec, |last, path| match path {
151 PathType::Object(path) => self.handle_path(&last, path),
152 PathType::Array(pos) => self.handle_array(&last, *pos),
153 PathType::Wildcard => self.handle_wildcard(&last),
154 PathType::RecursiveWildcard => {
155 [&last[..], &self.handle_recursive_wildcard(&last)[..]].concat()
156 }
157 });
158 }
159
160 vec
161 }
162
163 pub fn keys_at(&self, path: &[PathType]) -> Vec<&Key> {
180 self.value_at(path)
181 .iter()
182 .filter_map(|entry| {
183 if let EntryType::JSONObject(hash) = &entry.entry_type {
184 return Some(
185 hash.iter()
186 .filter_map(|(_, (key, _))| self.keys.get(*key))
187 .collect(),
188 );
189 }
190
191 None
192 })
193 .collect::<Vec<Vec<&Key>>>()
194 .into_iter()
195 .flatten()
196 .collect::<Vec<&Key>>()
197 }
198}