firebase_rs_sdk/util/
deep_copy.rs

1use 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}