in avro/src/schema.rs [471:532]
fn resolve<'n>(
&mut self,
schemata: Vec<&'s Schema>,
enclosing_namespace: &Namespace,
known_schemata: Option<&'n NamesRef<'n>>,
) -> AvroResult<()> {
for schema in schemata {
match schema {
Schema::Array(schema) => {
self.resolve(vec![&schema.items], enclosing_namespace, known_schemata)?
}
Schema::Map(schema) => {
self.resolve(vec![&schema.types], enclosing_namespace, known_schemata)?
}
Schema::Union(UnionSchema { schemas, .. }) => {
for schema in schemas {
self.resolve(vec![schema], enclosing_namespace, known_schemata)?
}
}
Schema::Enum(EnumSchema { name, .. }) | Schema::Fixed(FixedSchema { name, .. }) => {
let fully_qualified_name = name.fully_qualified_name(enclosing_namespace);
if self
.names_ref
.insert(fully_qualified_name.clone(), schema)
.is_some()
{
return Err(Error::AmbiguousSchemaDefinition(fully_qualified_name));
}
}
Schema::Record(RecordSchema { name, fields, .. }) => {
let fully_qualified_name = name.fully_qualified_name(enclosing_namespace);
if self
.names_ref
.insert(fully_qualified_name.clone(), schema)
.is_some()
{
return Err(Error::AmbiguousSchemaDefinition(fully_qualified_name));
} else {
let record_namespace = fully_qualified_name.namespace;
for field in fields {
self.resolve(vec![&field.schema], &record_namespace, known_schemata)?
}
}
}
Schema::Ref { name } => {
let fully_qualified_name = name.fully_qualified_name(enclosing_namespace);
// first search for reference in current schemata, then look into external references.
if !self.names_ref.contains_key(&fully_qualified_name) {
let is_resolved_with_known_schemas = known_schemata
.as_ref()
.map(|names| names.contains_key(&fully_qualified_name))
.unwrap_or(false);
if !is_resolved_with_known_schemas {
return Err(Error::SchemaResolutionError(fully_qualified_name));
}
}
}
_ => (),
}
}
Ok(())
}