1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use serde_json::Value;
fn normalize_value_recursively(v: &mut Value, normalize: &mut dyn FnMut(&str, &mut Value)) {
match v {
Value::Array(arr) => {
for v in arr {
normalize_value_recursively(v, normalize);
}
}
Value::Object(obj) => {
for (k, v) in obj.iter_mut() {
normalize(k, v);
}
for (_, v) in obj.iter_mut() {
normalize_value_recursively(v, normalize);
}
}
_ => {}
}
}
pub fn diff_json_value(
a: &mut Value,
b: &mut Value,
normalize: &mut dyn FnMut(&str, &mut Value),
) -> bool {
normalize_value_recursively(a, normalize);
normalize_value_recursively(b, normalize);
remove_common(a, b)
}
fn remove_common(a: &mut Value, b: &mut Value) -> bool {
if *a == *b {
return true;
}
match (&mut *a, &mut *b) {
(Value::Object(a), Value::Object(b)) => {
if a.is_empty() && b.is_empty() {
return true;
}
a.retain(|key, a_v| {
if let Some(b_v) = b.get_mut(key) {
if remove_common(a_v, b_v) {
b.remove(key);
return false;
}
} else {
if a_v == &Value::Null {
return false;
}
}
true
});
b.retain(|key, b_v| {
if b_v == &Value::Null && !a.contains_key(key) {
return false;
}
true
});
}
(Value::Array(a), Value::Array(b)) => {
if a.len() == b.len() {
for (a_v, b_v) in a.iter_mut().zip(b.iter_mut()) {
remove_common(a_v, b_v);
}
}
}
_ => {}
}
false
}