serde_json_utils/
lib.rs

1use crate::utils::{DedupeHashValue, HashValue};
2use serde_json::Value::{self, *};
3use std::collections::HashSet;
4
5#[cfg(test)]
6mod tests;
7mod utils;
8
9pub trait JsonUtils {
10    /// Remove `Null` value fields from serde_json::Value
11    /// ## Example
12    /// ```rust
13    /// use serde_json::{Value, from_str};
14    /// use serde_json_utils::{JsonUtils};
15    ///
16    /// let mut x: Value = from_str(r###"{"key1": null, "key2": "foo"}"###).unwrap();
17    /// let x_result: Value = from_str(r###"{"key2": "foo"}"###).unwrap();
18    ///
19    /// x.skip_null();
20    /// assert_eq!(x, x_result);
21    /// ```
22    fn skip_null(&mut self);
23
24    /// Remove `Null` value fields & `empty` value fields from serde_json::Value
25    /// ## Example
26    /// ```rust
27    /// use serde_json::{Value, from_str};
28    /// use serde_json_utils::{JsonUtils};
29    ///
30    /// let mut x: Value = from_str(r###"{"key1": null, "key2": "foo", "key3": [], "key4": {}}"###).unwrap();
31    /// let x_result: Value = from_str(r###"{"key2": "foo"}"###).unwrap();
32    ///
33    /// x.skip_null_and_empty();
34    /// assert_eq!(x, x_result);
35    /// ```
36    fn skip_null_and_empty(&mut self);
37
38    /// `Dedup` array of json's from serde_json::Value
39    /// ## Example
40    /// ```rust
41    /// use serde_json::{Value, from_str};
42    /// use serde_json_utils::{JsonUtils};
43    ///
44    /// let mut x: Value = from_str(r###"[{"key1": "foo", "key2": "bar", "key3": [1, 1, 2]}, {"key1": "foo", "key2": "bar", "key3": [1, 1, 2]}]"###).unwrap();
45    /// let x_result: Value = from_str(r###"[{"key1": "foo", "key2": "bar", "key3": [1, 2]}]"###).unwrap();
46    ///
47    /// x.dedup();
48    /// assert_eq!(x, x_result);
49    /// ```
50    fn dedup(&mut self);
51
52    fn merge_similar(&mut self);
53}
54
55impl JsonUtils for Value {
56    /// Remove `Null` value fields from serde_json::Value
57    /// ## Example
58    /// ```rust
59    /// use serde_json::{Value, from_str};
60    /// use serde_json_utils::{JsonUtils};
61    ///
62    /// let mut x: Value = from_str(r###"{"key1": null, "key2": "foo"}"###).unwrap();
63    /// let x_result: Value = from_str(r###"{"key2": "foo"}"###).unwrap();
64    ///
65    /// x.skip_null();
66    /// assert_eq!(x, x_result);
67    /// ```
68    fn skip_null(&mut self) {
69        remove_nulls(self, false);
70    }
71
72    /// Remove `Null` value fields & `empty` value fields from serde_json::Value
73    /// ## Example
74    /// ```rust
75    /// use serde_json::{Value, from_str};
76    /// use serde_json_utils::{JsonUtils};
77    ///
78    /// let mut x: Value = from_str(r###"{"key1": null, "key2": "foo", "key3": [], "key4": {}}"###).unwrap();
79    /// let x_result: Value = from_str(r###"{"key2": "foo"}"###).unwrap();
80    ///
81    /// x.skip_null_and_empty();
82    /// assert_eq!(x, x_result);
83    /// ```
84    fn skip_null_and_empty(&mut self) {
85        remove_nulls(self, true);
86    }
87
88    /// `Dedup` array of json's from serde_json::Value
89    /// ## Example
90    /// ```rust
91    /// use serde_json::{Value, from_str};
92    /// use serde_json_utils::{JsonUtils};
93    ///
94    /// let mut x: Value = from_str(r###"[{"key1": "foo", "key2": "bar", "key3": [1, 1, 2]}, {"key1": "foo", "key2": "bar", "key3": [1, 1, 2]}]"###).unwrap();
95    /// let x_result: Value = from_str(r###"[{"key1": "foo", "key2": "bar", "key3": [1, 2]}]"###).unwrap();
96    ///
97    /// x.dedup();
98    /// assert_eq!(x, x_result);
99    /// ```
100    fn dedup(&mut self) {
101        match self {
102            Null => {}
103            Bool(_) => {}
104            Number(_) => {}
105            String(_) => {}
106            Array(a) => {
107                let mut aa = a.clone();
108                for v in &mut aa {
109                    v.dedup();
110                }
111                let mut set = HashSet::new();
112                let mut candidates = vec![];
113                for v in &aa {
114                    if !set.contains(&DedupeHashValue(v)) {
115                        set.insert(DedupeHashValue(v));
116                        candidates.push(v.clone());
117                    }
118                }
119                a.clear();
120                a.extend(candidates);
121            }
122            Object(o) => {
123                for (_, v) in o.iter_mut() {
124                    v.dedup();
125                }
126            }
127        }
128    }
129
130    fn merge_similar(&mut self) {
131        match self {
132            Array(arr) => {
133                let mut res: HashSet<HashValue> = HashSet::new();
134                let aarr = arr.clone();
135                for v in aarr {
136                    if let Some(s) = res.take(&HashValue(v.clone())) {
137                        if let Ok(m) = merge_similar_objects(&s.0, &v) {
138                            res.insert(HashValue(m));
139                        } else {
140                            res.insert(s);
141                            res.insert(HashValue(v.clone()));
142                        }
143                    } else {
144                        res.insert(HashValue(v.clone()));
145                    }
146                }
147                arr.clear();
148                arr.extend(res.into_iter().map(|s| s.0).collect::<Vec<Value>>());
149            }
150            Object(obj) => {
151                for (_k, v) in obj {
152                    v.merge_similar();
153                }
154            }
155            _ => {}
156        }
157    }
158}
159
160/// Remove `Null` value fields & `empty` value fields from serde_json::Value
161fn remove_nulls(val: &mut Value, with_empties: bool) -> bool {
162    match val {
163        Null => {
164            return true;
165        }
166        Bool(_) => {}
167        Number(_) => {}
168        String(_) => {}
169        Array(arr) => {
170            if with_empties && arr.is_empty() {
171                return true;
172            }
173            let mut candidates = vec![];
174            for v in &mut arr.clone() {
175                if !remove_nulls(v, with_empties) {
176                    candidates.push(v.clone());
177                }
178            }
179            arr.clear();
180            arr.extend(candidates);
181        }
182        Object(obj) => {
183            if with_empties && obj.is_empty() {
184                return true;
185            }
186            let mut candidates = vec![];
187            for (k, v) in obj.iter_mut() {
188                if remove_nulls(v, with_empties) {
189                    candidates.push(k.clone());
190                }
191            }
192            for c in candidates {
193                obj.remove(&c);
194            }
195        }
196    }
197    false
198}
199
200/// merge similar objects
201fn merge_similar_objects(p: &Value, v: &Value) -> Result<Value, ()> {
202    match (p, v) {
203        (Object(a), Object(b)) => {
204            if HashValue(p.clone()) != HashValue(v.clone()) {
205                return Err(());
206            }
207            let mut res = serde_json::Map::new();
208            for (k, v) in a {
209                let bv = b.get(k).unwrap();
210                if let (Array(_arr1), Array(_arr2)) = (v, bv) {
211                    if v.eq(bv) {
212                        res.insert(k.clone(), v.clone());
213                    } else {
214                        res.insert(k.clone(), Array(vec![v.clone(), bv.clone()]));
215                    }
216                } else if let (Array(arr1), _) = (v, bv) {
217                    let mut aaa = arr1.clone();
218                    if !aaa.contains(bv) {
219                        aaa.push(bv.clone());
220                    }
221                    res.insert(k.clone(), Array(aaa));
222                } else if v.eq(bv) {
223                    res.insert(k.clone(), v.clone());
224                } else {
225                    res.insert(k.clone(), Array(vec![v.clone(), bv.clone()]));
226                }
227            }
228            Ok(Object(res))
229        }
230        _ => Err(()),
231    }
232}