serde_patch/
apply_patch.rs1use serde::{Serialize, de::DeserializeOwned};
2use serde_json::{Map, Value};
3
4pub fn apply<T>(current: T, patch_json: &str) -> Result<T, serde_json::Error>
22where
23 T: Serialize + DeserializeOwned,
24{
25 let mut current_val = serde_json::to_value(current)?;
26
27 let patch_val: Value = serde_json::from_str(patch_json)?;
28
29 merge_patch(&mut current_val, &patch_val);
30
31 serde_json::from_value(current_val)
32}
33
34fn merge_patch(target: &mut Value, patch: &Value) {
36 if let Value::Object(patch_map) = patch {
37 if !target.is_object() {
38 *target = Value::Object(Map::new());
39 }
40
41 let target_map = target.as_object_mut().unwrap();
42
43 for (key, patch_value) in patch_map {
44 if patch_value.is_null() {
45 target_map.remove(key);
46 } else {
47 let target_entry = target_map.entry(key.clone()).or_insert(Value::Null);
48 merge_patch(target_entry, patch_value);
49 }
50 }
51 } else {
52 *target = patch.clone();
53 }
54}