firebase_rs_sdk/util/
deep_copy.rs1use serde_json::{Map, Value};
2
3pub fn deep_copy(value: &Value) -> Value {
4 deep_extend(&Value::Null, value)
5}
6
7pub fn deep_extend(target: &Value, source: &Value) -> Value {
8 match source {
9 Value::Object(source_map) => {
10 let mut result = match target {
11 Value::Object(target_map) => target_map.clone(),
12 _ => Map::new(),
13 };
14 for (key, value) in source_map {
15 if key == "__proto__" {
16 continue;
17 }
18 let existing = result.get(key).cloned().unwrap_or(Value::Null);
19 result.insert(key.clone(), deep_extend(&existing, value));
20 }
21 Value::Object(result)
22 }
23 Value::Array(source_array) => Value::Array(source_array.clone()),
24 Value::Null | Value::Bool(_) | Value::Number(_) | Value::String(_) => source.clone(),
25 }
26}
27
28#[cfg(test)]
29mod tests {
30 use super::*;
31 use serde_json::json;
32
33 #[test]
34 fn deep_copy_preserves_nested_objects() {
35 let original = json!({"a": {"b": 2}});
36 let copy = deep_copy(&original);
37 assert_eq!(original, copy);
38 }
39
40 #[test]
41 fn deep_extend_merges_objects() {
42 let target = json!({"a": {"b": 1}, "c": 2});
43 let source = json!({"a": {"d": 3}});
44 let merged = deep_extend(&target, &source);
45 assert_eq!(merged["a"]["b"], json!(1));
46 assert_eq!(merged["a"]["d"], json!(3));
47 assert_eq!(merged["c"], json!(2));
48 }
49
50 #[test]
51 fn deep_extend_overwrites_arrays() {
52 let target = json!([1, 2, 3]);
53 let source = json!([4, 5]);
54 let merged = deep_extend(&target, &source);
55 assert_eq!(merged, source);
56 }
57}