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}