in components/support/nimbus-fml/src/defaults/validator.rs [162:237]
fn validate_enum_maps(
&self,
path: &ErrorPath,
type_ref: &TypeRef,
default: &Value,
) -> Result<()> {
match (type_ref, default) {
(TypeRef::Option(inner), v) => {
self.validate_enum_maps(path, inner, v)?
}
(TypeRef::EnumMap(enum_type, map_type), Value::Object(map))
if matches!(**enum_type, TypeRef::Enum(_)) =>
{
let enum_name = enum_type.name().unwrap();
let enum_def = self
.get_enum(enum_name)
// If this is thrown, there's a problem in validate_type_ref.
.unwrap_or_else(|| {
unreachable!("Enum {enum_name} is not defined in the manifest")
});
let mut unseen = HashSet::new();
if !matches!(**map_type, TypeRef::Option(_)) {
for variant in &enum_def.variants {
if !map.contains_key(&variant.name) {
unseen.insert(variant.name());
}
}
if !unseen.is_empty() {
let path = path.open_brace();
return Err(FMLError::ValidationError(
path.path,
format!("Enum map {enum_name} is missing values for {unseen:?}"),
));
}
}
for (key, value) in map {
self.validate_enum_maps(&path.enum_map_key(enum_name, key), map_type, value)?
}
}
(TypeRef::EnumMap(_, map_type), Value::Object(map)) // Map<string-alias, T>
| (TypeRef::StringMap(map_type), Value::Object(map)) => {
for (key, value) in map {
self.validate_enum_maps(&path.map_key(key), map_type, value)?
}
}
(TypeRef::List(list_type), Value::Array(arr)) => {
for (index, value) in arr.iter().enumerate() {
self.validate_enum_maps(&path.array_index(index), list_type, value)?
}
}
(TypeRef::Object(obj_name), Value::Object(map)) => {
let obj_def = self
.get_object(obj_name)
// If this is thrown, there's a problem in validate_type_ref.
.unwrap_or_else(|| {
unreachable!("Object {obj_name} is not defined in the manifest")
});
let path = path.object_value(obj_name);
for prop in &obj_def.props {
if let Some(value) = map.get(&prop.name) {
self.validate_enum_maps(&path.property(&prop.name), &prop.typ, value)?
}
}
}
_ => (),
};
Ok(())
}