fn validate_enum_maps()

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(())
    }