oa_gateway_uci/xsd/
references.rsuse std::collections::BTreeSet;
use crate::schema::{ComplexContent, Schema};
use crate::UciError;
const MAX_REPORTED: usize = 10;
pub(super) fn check_references(schema: &Schema) -> Result<(), UciError> {
let mut missing = BTreeSet::new();
for global in schema.global_elements.values() {
note_missing(schema, &global.type_name, &mut missing);
}
for ct in schema.complex_types.values() {
let (base, groups) = match &ct.content {
ComplexContent::Groups(groups) => (None, groups),
ComplexContent::Extension { base, extra } => (Some(base), extra),
};
if let Some(base) = base {
note_missing(schema, base, &mut missing);
}
for el in groups.iter().flat_map(|g| g.elements.iter()) {
note_missing(schema, &el.type_name, &mut missing);
}
}
for simple in schema.simple_types.values() {
note_missing(schema, &simple.base, &mut missing);
}
if missing.is_empty() {
return Ok(());
}
let shown: Vec<&str> = missing
.iter()
.take(MAX_REPORTED)
.map(String::as_str)
.collect();
let suffix = if missing.len() > shown.len() {
format!(", and {} more", missing.len() - shown.len())
} else {
String::new()
};
Err(UciError::Xsd(format!(
"{} type reference(s) do not resolve, so a schema document is probably missing: {}{suffix}",
missing.len(),
shown.join(", ")
)))
}
fn note_missing(schema: &Schema, type_name: &str, missing: &mut BTreeSet<String>) {
let known = type_name.starts_with("xs:")
|| schema.complex_types.contains_key(type_name)
|| schema.simple_types.contains_key(type_name);
if !known {
missing.insert(type_name.to_owned());
}
}