1#![allow(dead_code)]
2use serde_json::{Map, Value};
3
4pub trait Merge {
6 fn merge(&mut self, new_json_value: Value);
8 fn merge_in(&mut self, json_pointer: &str, new_json_value: Value);
10}
11
12pub fn merge_json(a: &mut Value, b: Value) {
38 match (a, b) {
39 (a @ &mut Value::Object(_), Value::Object(b)) => {
40 let a = a.as_object_mut().unwrap();
41 for (k, v) in b {
42 merge_json(a.entry(k).or_insert(Value::Null), v);
43 }
44 }
45 (a @ &mut Value::Array(_), Value::Array(b)) => {
46 let a = a.as_array_mut().unwrap();
47 a.extend(b);
48 a.dedup();
49 }
50 (a @ &mut Value::Array(_), Value::Object(b)) => {
51 let a = a.as_array_mut().unwrap();
52 a.push(Value::Object(b));
53 a.dedup();
54 }
55 (a, b) => *a = b,
56 }
57}
58
59pub fn merge_json_and_yaml(a: &mut Value, raw_str: String) {
78 let try_json = serde_yaml::from_str::<Value>(&raw_str).unwrap();
79 merge_json(a, try_json)
80}
81
82impl Merge for Value {
83 fn merge(&mut self, new_json_value: Value) {
124 merge(self, &new_json_value);
125 }
126 fn merge_in(&mut self, json_pointer: &str, new_json_value: Value) {
167 let fields: Vec<&str> = json_pointer.split('/').skip(1).collect();
168
169 merge_in(self, fields, new_json_value);
170 }
171}
172
173fn merge(a: &mut Value, b: &Value) {
174 match (a, b) {
175 (&mut Value::Object(ref mut a), Value::Object(b)) => {
176 for (k, v) in b {
177 merge(a.entry(k.clone()).or_insert(Value::Null), v);
178 }
179 }
180 (&mut Value::Array(ref mut a), Value::Array(b)) => {
181 a.extend(b.clone());
182 a.dedup();
183 }
184 (&mut Value::Array(ref mut a), Value::Object(b)) => {
185 a.push(Value::Object(b.clone()));
186 a.dedup();
187 }
188 (a, b) => {
189 *a = b.clone();
190 }
191 }
192}
193
194fn merge_in(json_value: &mut Value, fields: Vec<&str>, new_json_value: Value) {
195 if fields.is_empty() {
196 return json_value.merge(new_json_value);
197 }
198
199 let mut fields = fields.clone();
200 let field = fields.remove(0);
201
202 if field.is_empty() {
203 return json_value.merge(new_json_value);
204 }
205
206 match json_value.pointer_mut(format!("/{}", field).as_str()) {
207 Some(json_targeted) => {
209 if !fields.is_empty() {
210 merge_in(json_targeted, fields, new_json_value);
211 } else {
212 json_targeted.merge(new_json_value);
213 }
214 }
215 None => {
218 let new_value = match field.parse::<usize>().ok() {
219 Some(position) => {
220 let mut vec = Vec::default();
221 match vec.get(position) {
222 Some(_) => vec.insert(position, Value::default()),
223 None => vec.push(Value::default()),
224 }
225 Value::Array(vec)
226 }
227 None => {
228 let mut map = Map::default();
229 map.insert(field.to_string(), Value::default());
230 Value::Object(map)
231 }
232 };
233
234 match (json_value.clone(), new_value.clone()) {
235 (Value::Array(vec), Value::Object(_)) => {
236 json_value.merge(new_value);
237 let size = vec.len().to_string();
238 let mut new_fields: Vec<&str> = vec![&size, field];
239 new_fields.append(&mut fields.clone());
240 merge_in(json_value, new_fields, new_json_value);
241 }
242 (_, _) => {
243 let mut new_fields: Vec<&str> = vec![field];
244 new_fields.append(&mut fields.clone());
245 json_value.merge(new_value);
246 merge_in(json_value, new_fields, new_json_value);
247 }
248 }
249 }
250 };
251}
252
253#[cfg(test)]
254mod tests {
255 use super::*;
256 use serde_json::json;
257
258 #[test]
259 fn can_merge_two_valid_jsons() {
260 let mut a = json!({
261 "title": "This is a title",
262 "person" : {
263 "firstName" : "John",
264 "lastName" : "Doe"
265 },
266 "cities":[ "london", "paris" ]
267 });
268
269 let b = json!({
270 "title": "This is another title",
271 "person" : {
272 "firstName" : "Jane"
273 },
274 "cities":[ "colombo" ]
275 });
276 merge_json(&mut a, b);
277
278 assert_eq!(
279 a,
280 json!({
281 "title": "This is another title",
282 "person" : {
283 "firstName" : "Jane",
284 "lastName" : "Doe"
285 },
286 "cities":[ "london", "paris", "colombo" ]
287 })
288 );
289 }
290
291 #[test]
292 fn it_should_merge_array_string() {
293 let mut first_json_value: Value = serde_json::from_str(r#"["a","b"]"#).unwrap();
294 let secound_json_value: Value = serde_json::from_str(r#"["b","c"]"#).unwrap();
295 first_json_value.merge(secound_json_value);
296 assert_eq!(r#"["a","b","c"]"#, first_json_value.to_string());
297 }
298 #[test]
299 fn it_should_merge_array_object() {
300 let mut first_json_value: Value =
301 serde_json::from_str(r#"[{"value":"a"},{"value":"b"}]"#).unwrap();
302 let secound_json_value: Value =
303 serde_json::from_str(r#"[{"value":"b"},{"value":"c"}]"#).unwrap();
304 first_json_value.merge(secound_json_value);
305 assert_eq!(
306 r#"[{"value":"a"},{"value":"b"},{"value":"c"}]"#,
307 first_json_value.to_string()
308 );
309 }
310 #[test]
311 fn it_should_merge_object() {
312 let mut first_json_value: Value =
313 serde_json::from_str(r#"{"value1":"a","value2":"b"}"#).unwrap();
314 let secound_json_value: Value =
315 serde_json::from_str(r#"{"value1":"a","value2":"c","value3":"d"}"#).unwrap();
316 first_json_value.merge(secound_json_value);
317 assert_eq!(
318 r#"{"value1":"a","value2":"c","value3":"d"}"#,
319 first_json_value.to_string()
320 );
321 }
322 #[test]
323 fn it_should_merge_string() {
324 let mut value_a: Value = Value::String("a".to_string());
325 let value_b: Value = Value::String("b".to_string());
326 value_a.merge(value_b.clone());
327 assert_eq!(value_b.to_string(), value_a.to_string());
328 }
329 #[test]
330 fn it_should_merge_an_array_in_a_specifique_field_path() {
331 let mut value_a: Value = serde_json::from_str(r#"{"my_array":[{"a":"t"}]}"#).unwrap();
332 let value_b: Value = serde_json::from_str(r#"["b","c"]"#).unwrap();
333 value_a.merge_in("/my_array", value_b);
334 assert_eq!(r#"{"my_array":[{"a":"t"},"b","c"]}"#, value_a.to_string());
335 }
336 #[test]
337 fn it_should_merge_an_object_in_a_specifique_field_path() {
338 let mut value_a: Value = serde_json::from_str(r#"{"my_array":[{"a":"t"}]}"#).unwrap();
339 let value_b: Value = serde_json::from_str(r#"{"b":"c"}"#).unwrap();
340 value_a.merge_in("/my_array", value_b);
341 assert_eq!(r#"{"my_array":[{"a":"t"},{"b":"c"}]}"#, value_a.to_string());
342 }
343 #[test]
344 fn it_should_merge_in_an_object_in_specifique_path_position() {
345 let mut value_a: Value = serde_json::from_str(r#"{"my_array":[{"a":"t"}]}"#).unwrap();
346 let value_b: Value = serde_json::from_str(r#"{"b":"c"}"#).unwrap();
347 value_a.merge_in("/my_array/0", value_b);
348 assert_eq!(r#"{"my_array":[{"a":"t","b":"c"}]}"#, value_a.to_string());
349 }
350 #[test]
351 fn it_should_merge_an_array_in_specifique_path_position() {
352 let mut value_a: Value = serde_json::from_str(r#"{"my_array":[{"a":"t"}]}"#).unwrap();
353 let value_b: Value = serde_json::from_str(r#"{"b":"c"}"#).unwrap();
354 value_a.merge_in("/my_array/1", value_b);
355 assert_eq!(r#"{"my_array":[{"a":"t"},{"b":"c"}]}"#, value_a.to_string());
356 }
357 #[test]
358 fn it_should_merge_in_root_array() {
359 let mut json_value: Value = serde_json::from_str(r#"["value"]"#).unwrap();
360 let json_value_to_merge: Value = serde_json::from_str(r#"["new_value"]"#).unwrap();
361 json_value.merge_in("/", json_value_to_merge);
362 assert_eq!(r#"["value","new_value"]"#, json_value.to_string());
363 }
364 #[test]
365 fn it_should_merge_in_root_object() {
366 let mut json_value: Value = serde_json::from_str(r#"{"field":"value"}"#).unwrap();
367 let json_value_to_merge: Value = serde_json::from_str(r#"{"field2":"value2"}"#).unwrap();
368 json_value.merge_in("/", json_value_to_merge);
369 assert_eq!(
370 r#"{"field":"value","field2":"value2"}"#,
371 json_value.to_string()
372 );
373 }
374 #[test]
375 fn it_should_merge_null_in_specifique_path() {
376 let mut json_value: Value = serde_json::from_str(r#"{"field":{"child":"value"}}"#).unwrap();
377 let json_value_null: Value = Value::Null;
378 json_value.merge_in("/field", json_value_null);
379 assert_eq!(r#"{"field":null}"#, json_value.to_string());
380 }
381}