use serde_json::Value;
pub fn deep_diff(path: &str, java: &Value, rust: &Value) -> Vec<String> {
let mut diffs = Vec::new();
match (java, rust) {
(Value::Object(j), Value::Object(r)) => {
for (key, jv) in j {
match r.get(key) {
Some(rv) => diffs.extend(deep_diff(&format!("{}.{}", path, key), jv, rv)),
None => diffs.push(format!("{}.{}: missing in Rust", path, key)),
}
}
for key in r.keys() {
if !j.contains_key(key) {
diffs.push(format!("{}.{}: extra in Rust", path, key));
}
}
}
(Value::Array(j), Value::Array(r)) => {
if j.len() != r.len() {
diffs.push(format!(
"{}: array length Java={} Rust={}",
path,
j.len(),
r.len()
));
}
for (i, (jv, rv)) in j.iter().zip(r.iter()).enumerate() {
diffs.extend(deep_diff(&format!("{}[{}]", path, i), jv, rv));
}
}
_ => {
if java != rust {
diffs.push(format!("{}: Java={} Rust={}", path, java, rust));
}
}
}
diffs
}
pub fn filter_dynamic_diffs(diffs: &[String]) -> Vec<&String> {
diffs
.iter()
.filter(|d| {
let dl = d.to_lowercase();
!dl.contains(".id:")
&& !dl.contains("time:")
&& !dl.contains("timestamp:")
&& !dl.contains("createtime:")
&& !dl.contains("updatetime:")
&& !dl.contains("created_at:")
&& !dl.contains("updated_at:")
})
.collect()
}
pub fn filter_fields(value: &Value, ignore_fields: &[&str]) -> Value {
if let Value::Object(map) = value {
let filtered: serde_json::Map<String, Value> = map
.iter()
.filter(|(k, _)| !ignore_fields.contains(&k.as_str()))
.map(|(k, v)| (k.clone(), v.clone()))
.collect();
Value::Object(filtered)
} else {
value.clone()
}
}