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