1use serde_json::Value;
2
3pub fn json_merge_patch(target: &mut Value, patch: &Value) {
4 match patch {
5 Value::Object(patch_obj) => {
6 if !(target.is_object()
7 || target.is_array() && patch_obj.keys().all(|key| key.parse::<usize>().is_ok()))
8 {
9 *target = Value::Object(serde_json::Map::new());
10 }
11
12 if let Value::Object(target_obj) = target {
13 for (key, value) in patch_obj {
14 if value.is_null() {
15 target_obj.remove(key);
16 } else {
17 let target_value =
18 target_obj.entry(key.clone()).or_insert_with(|| Value::Null);
19 json_merge_patch(target_value, value);
20 }
21 }
22 } else if let Value::Array(target_arr) = target {
23 for (key, value) in patch_obj {
24 if let Ok(index) = key.parse::<usize>() {
25 if value.is_null() && index < target_arr.len() {
26 target_arr.remove(index);
27 } else if index < target_arr.len() {
28 json_merge_patch(&mut target_arr[index], value);
29 } else {
30 while target_arr.len() < index {
32 target_arr.push(Value::Null);
33 }
34 target_arr.push(value.clone());
35 }
36 }
37 }
38 }
39 }
40 Value::Array(patch_arr) => {
41 *target = serde_json::Value::Array(
42 patch_arr
43 .clone()
44 .into_iter()
45 .filter(|value| !value.is_null())
46 .collect(),
47 );
48 }
49 _ => *target = patch.clone(),
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn test_json_merge_patch_should_merge_objects_and_override_field() {
59 let mut target = serde_json::from_str(r#"{"a": "b", "c": {"d": "e", "f": "g"}}"#).unwrap();
60 let patch = serde_json::from_str(r#"{"a": "z", "c": {"f": null}}"#).unwrap();
61
62 json_merge_patch(&mut target, &patch);
63
64 let expected: serde_json::Value =
65 serde_json::from_str(r#"{"a": "z", "c": {"d": "e"}}"#).unwrap();
66 assert_eq!(target, expected);
67 }
68
69 #[test]
70 fn test_json_merge_patch_should_override_field_in_object() {
71 let mut target = serde_json::from_str(r#"{"a": "b"}"#).unwrap();
72 let patch = serde_json::from_str(r#"{"a": "c"}"#).unwrap();
73 let expected: serde_json::Value = serde_json::from_str(r#"{"a": "c"}"#).unwrap();
74
75 json_merge_patch(&mut target, &patch);
76
77 assert_eq!(target, expected);
78 }
79
80 #[test]
81 fn test_json_merge_patch_should_add_field_to_object() {
82 let mut target = serde_json::from_str(r#"{"a": "b"}"#).unwrap();
83 let patch = serde_json::from_str(r#"{"b": "c"}"#).unwrap();
84 let expected: serde_json::Value = serde_json::from_str(r#"{"a": "b", "b": "c"}"#).unwrap();
85
86 json_merge_patch(&mut target, &patch);
87
88 assert_eq!(target, expected);
89 }
90
91 #[test]
92 fn test_json_merge_patch_should_remove_field_from_object() {
93 let mut target = serde_json::from_str(r#"{"a": "b", "b": "c"}"#).unwrap();
94 let patch = serde_json::from_str(r#"{"a": null}"#).unwrap();
95 let expected: serde_json::Value = serde_json::from_str(r#"{"b": "c"}"#).unwrap();
96
97 json_merge_patch(&mut target, &patch);
98
99 assert_eq!(target, expected);
100 }
101
102 #[test]
103 fn test_json_merge_patch_should_override_field_in_array() {
104 let mut target = serde_json::from_str(r#"{"a": ["b"]}"#).unwrap();
105 let patch = serde_json::from_str(r#"{"a": "c"}"#).unwrap();
106 let expected: serde_json::Value = serde_json::from_str(r#"{"a": "c"}"#).unwrap();
107
108 json_merge_patch(&mut target, &patch);
109
110 assert_eq!(target, expected);
111 }
112
113 #[test]
114 fn test_json_merge_patch_should_replace_array_with_scalar() {
115 let mut target = serde_json::from_str(r#"{"a": "c"}"#).unwrap();
116 let patch = serde_json::from_str(r#"{"a": ["b"]}"#).unwrap();
117 let expected: serde_json::Value = serde_json::from_str(r#"{"a": ["b"]}"#).unwrap();
118
119 json_merge_patch(&mut target, &patch);
120
121 assert_eq!(target, expected);
122 }
123
124 #[test]
125 fn test_json_merge_patch_should_merge_objects_in_object() {
126 let mut target = serde_json::from_str(r#"{"a": {"b": "c"}}"#).unwrap();
127 let patch = serde_json::from_str(r#"{"a": {"b": "d", "c": null}}"#).unwrap();
128 let expected: serde_json::Value = serde_json::from_str(r#"{"a": {"b": "d"}}"#).unwrap();
129
130 json_merge_patch(&mut target, &patch);
131
132 assert_eq!(target, expected);
133 }
134
135 #[test]
136 fn test_json_merge_patch_should_replace_array_with_value() {
137 let mut target = serde_json::from_str(r#"{"a": [{"b": "c"}]}"#).unwrap();
138 let patch = serde_json::from_str(r#"{"a": [1]}"#).unwrap();
139 let expected: serde_json::Value = serde_json::from_str(r#"{"a": [1]}"#).unwrap();
140
141 json_merge_patch(&mut target, &patch);
142
143 assert_eq!(target, expected);
144 }
145
146 #[test]
147 fn test_json_merge_patch_should_merge_nested_objects_and_remove_leaf_nodes() {
148 let mut target = serde_json::from_str(r#"{}"#).unwrap();
149 let patch = serde_json::from_str(r#"{"a": {"bb": {"ccc": null}}}"#).unwrap();
150 let expected: serde_json::Value = serde_json::from_str(r#"{"a": {"bb": {}}}"#).unwrap();
151
152 json_merge_patch(&mut target, &patch);
153
154 assert_eq!(target, expected);
155 }
156
157 #[test]
158 fn test_json_merge_patch_should_replace_scalar_with_scalar() {
159 let mut target = serde_json::from_str(r#"{"a": "b"}"#).unwrap();
160 let patch = serde_json::from_str(r#"["c"]"#).unwrap();
161 let expected: serde_json::Value = serde_json::from_str(r#"["c"]"#).unwrap();
162
163 json_merge_patch(&mut target, &patch);
164
165 assert_eq!(target, expected);
166 }
167
168 #[test]
169 fn test_json_merge_patch_should_replace_scalar_with_null() {
170 let mut target = serde_json::from_str(r#"{"a": "foo"}"#).unwrap();
171 let patch = serde_json::Value::Null;
172
173 json_merge_patch(&mut target, &patch);
174
175 assert_eq!(target, serde_json::Value::Null);
176 }
177
178 #[test]
179 fn test_json_merge_patch_should_replace_scalar_with_string() {
180 let mut target = serde_json::from_str(r#"{"a": "foo"}"#).unwrap();
181 let patch = serde_json::from_str(r#""bar""#).unwrap();
182 let expected: serde_json::Value = serde_json::from_str(r#""bar""#).unwrap();
183
184 json_merge_patch(&mut target, &patch);
185
186 assert_eq!(target, expected);
187 }
188
189 #[test]
190 fn test_json_merge_patch_should_merge_null_with_scalar() {
191 let mut target = serde_json::from_str(r#"{"e": null}"#).unwrap();
192 let patch = serde_json::from_str(r#"{"a": 1}"#).unwrap();
193 let expected: serde_json::Value = serde_json::from_str(r#"{"e": null, "a": 1}"#).unwrap();
194
195 json_merge_patch(&mut target, &patch);
196
197 assert_eq!(target, expected);
198 }
199
200 #[test]
201 fn test_json_merge_patch_should_replace_array_with_object() {
202 let mut target = serde_json::from_str(r#"{"a": []}"#).unwrap();
203 let patch = serde_json::from_str(r#"{"a": {"b": "c"}}"#).unwrap();
204 let expected: serde_json::Value = serde_json::from_str(r#"{"a": {"b": "c"}}"#).unwrap();
205
206 json_merge_patch(&mut target, &patch);
207
208 assert_eq!(target, expected);
209 }
210
211 #[test]
212 fn test_json_merge_patch_should_merge_objects_in_array() {
213 let mut target = serde_json::from_str(r#"[{"a": "b"}, {"c": "d"}]"#).unwrap();
214 let patch = serde_json::from_str(r#"{"1": {"e": "f"}}"#).unwrap();
215 let expected: serde_json::Value =
216 serde_json::from_str(r#"[{"a": "b"}, {"c": "d", "e": "f"}]"#).unwrap();
217
218 json_merge_patch(&mut target, &patch);
219
220 assert_eq!(target, expected);
221 }
222
223 #[test]
224 fn test_json_merge_patch_should_replace_object_with_array() {
225 let mut target = serde_json::from_str(r#"{"a": {"b": "c"}}"#).unwrap();
226 let patch = serde_json::from_str(r#"{"a": []}"#).unwrap();
227 let expected: serde_json::Value = serde_json::from_str(r#"{"a": []}"#).unwrap();
228
229 json_merge_patch(&mut target, &patch);
230
231 assert_eq!(target, expected);
232 }
233
234 #[test]
235 fn test_json_merge_patch_should_merge_arrays() {
236 let mut target = serde_json::from_str(r#"["a", "b"]"#).unwrap();
237 let patch = serde_json::from_str(r#"["c", "d"]"#).unwrap();
238 let expected: serde_json::Value = serde_json::from_str(r#"["c", "d"]"#).unwrap();
239
240 json_merge_patch(&mut target, &patch);
241
242 assert_eq!(target, expected);
243 }
244
245 #[test]
246 fn test_json_merge_patch_should_remove_key_from_object() {
247 let mut target = serde_json::from_str(r#"{"a": "b"}"#).unwrap();
248 let patch = serde_json::from_str(r#"{"a": null}"#).unwrap();
249 let expected: serde_json::Value = serde_json::from_str(r#"{}"#).unwrap();
250
251 json_merge_patch(&mut target, &patch);
252
253 assert_eq!(target, expected);
254 }
255
256 #[test]
257 fn test_json_merge_patch_should_remove_index_from_array() {
258 let mut target = serde_json::from_str(r#"["a", "b"]"#).unwrap();
259 let patch = serde_json::from_str(r#"{"1": null}"#).unwrap();
260 let expected: serde_json::Value = serde_json::from_str(r#"["a"]"#).unwrap();
261
262 json_merge_patch(&mut target, &patch);
263
264 assert_eq!(target, expected);
265 }
266
267 #[test]
268 fn test_json_merge_patch_should_remove_array_element() {
269 let mut target = serde_json::from_str(r#"[1, 2, 3]"#).unwrap();
270 let patch = serde_json::from_str(r#"[null, 2]"#).unwrap();
271 let expected: serde_json::Value = serde_json::from_str(r#"[2]"#).unwrap();
272
273 json_merge_patch(&mut target, &patch);
274
275 assert_eq!(target, expected);
276 }
277}