Recursive diff of two JSON values at a given path prefix.
(
diffs: &mut Vec<FieldDiff>,
prefix: &str,
old: &serde_json::Value,
new: &serde_json::Value,
)
| 152 | |
| 153 | /// Recursive diff of two JSON values at a given path prefix. |
| 154 | fn diff_values( |
| 155 | diffs: &mut Vec<FieldDiff>, |
| 156 | prefix: &str, |
| 157 | old: &serde_json::Value, |
| 158 | new: &serde_json::Value, |
| 159 | ) { |
| 160 | if old == new { |
| 161 | return; |
| 162 | } |
| 163 | |
| 164 | match (old, new) { |
| 165 | (serde_json::Value::Object(old_map), serde_json::Value::Object(new_map)) => { |
| 166 | diff_objects(diffs, prefix, old_map, new_map); |
| 167 | } |
| 168 | (serde_json::Value::Array(old_arr), serde_json::Value::Array(new_arr)) => { |
| 169 | diff_arrays(diffs, prefix, old_arr, new_arr); |
| 170 | } |
| 171 | // String fields: try to produce TextInsert/TextDelete for simple edits. |
| 172 | (serde_json::Value::String(old_s), serde_json::Value::String(new_s)) |
| 173 | if !prefix.is_empty() => |
| 174 | { |
| 175 | diff_strings(diffs, prefix, old_s, new_s); |
| 176 | } |
| 177 | _ => { |
| 178 | // Scalar or type mismatch — emit a Modified diff. |
| 179 | if !prefix.is_empty() { |
| 180 | diffs.push(FieldDiff { |
| 181 | field: prefix.to_owned(), |
| 182 | op: DiffOp::Modified, |
| 183 | old_value: Some(old.clone()), |
| 184 | new_value: Some(new.clone()), |
| 185 | }); |
| 186 | } |
| 187 | } |
| 188 | } |
| 189 | } |
| 190 | |
| 191 | /// Diff two JSON objects field-by-field. |
| 192 | fn diff_objects( |
no test coverage detected