use serde_json::Value;
pub fn deep_merge_json(target: &mut Value, source: Value) {
match (target, source) {
(Value::Object(t_map), Value::Object(s_map)) => {
for (k, v) in s_map {
deep_merge_json(t_map.entry(k).or_insert(Value::Null), v);
}
}
(slot, source) => {
*slot = source;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn keys_union_at_top_level() {
let mut t = json!({"a": 1, "b": 2});
deep_merge_json(&mut t, json!({"b": 20, "c": 3}));
assert_eq!(t, json!({"a": 1, "b": 20, "c": 3}));
}
#[test]
fn nested_objects_merge_recursively() {
let mut t = json!({"x": {"a": 1, "b": 2}});
deep_merge_json(&mut t, json!({"x": {"b": 20, "c": 3}}));
assert_eq!(t, json!({"x": {"a": 1, "b": 20, "c": 3}}));
}
#[test]
fn arrays_replace_target() {
let mut t = json!([1, 2, 3]);
deep_merge_json(&mut t, json!([9]));
assert_eq!(t, json!([9]));
}
#[test]
fn scalar_replaces_target() {
let mut t = json!(1);
deep_merge_json(&mut t, json!("hello"));
assert_eq!(t, json!("hello"));
}
}