json_position_parser/
tree.rs

1use super::types::Range;
2use std::collections::HashMap;
3
4#[derive(Debug)]
5pub enum EntryType {
6    JSONObject(HashMap<String, (usize, usize)>), // key, value
7    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    /// Get values at a path. Wildcard and recursive wildcard available.
131    ///
132    /// **Example**
133    /// ```
134    /// let text = "{ \"a\": { \"b\": ["c"] } }";
135    /// match parse_json(&text) {
136    ///     Ok(tree) => {
137    ///         let keys = tree.values_at(&[
138    ///            PathType::Object("a"),
139    ///            PathType::Object("b"),
140    ///            PathType::Array(0),
141    ///         ]);
142    ///     },
143    ///     Err(e) => println!("{:?}", e),
144    /// };
145    /// ```
146    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    /// Get keys at a path. Wildcard and recursive wildcard available.
164    ///
165    /// **Example**
166    /// ```
167    /// let text = "{ \"a\": { \"b\": ["c"] } }";
168    /// match parse_json(&text) {
169    ///     Ok(tree) => {
170    ///         let keys = tree.keys_at(&[
171    ///            PathType::Object("a"),
172    ///            PathType::Object("b"),
173    ///            PathType::Array(0),
174    ///         ]);
175    ///     },
176    ///     Err(e) => println!("{:?}", e),
177    /// };
178    /// ```
179    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}