pub(crate) trait SchemaVisitor {
fn visit(&mut self, schema: &mut serde_json::Value) -> bool;
}
pub(crate) fn walk_schema(
schema: &mut serde_json::Value,
visitor: &mut dyn SchemaVisitor,
depth: u8,
) {
if depth == 0 {
return;
}
if !visitor.visit(schema) {
return;
}
let Some(obj) = schema.as_object_mut() else {
return;
};
let prop_keys: Vec<String> = obj
.get("properties")
.and_then(|p| p.as_object())
.map(|p| p.keys().cloned().collect())
.unwrap_or_default();
for key in prop_keys {
if let Some(serde_json::Value::Object(props)) = obj.get_mut("properties")
&& let Some(child) = props.get_mut(&key)
{
walk_schema(child, visitor, depth - 1);
}
}
if let Some(items) = obj.get_mut("items") {
walk_schema(items, visitor, depth - 1);
}
for keyword in &["anyOf", "oneOf", "allOf"] {
if let Some(serde_json::Value::Array(variants)) = obj.get_mut(*keyword) {
for v in variants.iter_mut() {
walk_schema(v, visitor, depth - 1);
}
}
}
}