pub(crate) fn validate_property_spec(
    config_spec: &ProductConfigSpecProperties,
    property_spec: &HashMap<PropertyName, PropertySpec>,
) -> ValidationResult<()> {
    for (name, spec) in property_spec {
        let as_of_version = Version::parse(&spec.as_of_version)?;

        // 1) check for default values
        if let Some(values) = &spec.default_values {
            // 1.1) check if a provided default version matches as_of_version
            util::get_property_value_for_version(name, values, &as_of_version)?;

            for val in values {
                // 1.2) check if default matches the allowed values
                check_allowed_values(name, &val.value, &spec.allowed_values)?;
                // 1.3) check if default values match datatype (min, max, unit...)
                check_datatype(&config_spec.units, name, &val.value, &spec.datatype)?
            }
        }

        // 2) check for recommended values
        if let Some(values) = &spec.recommended_values {
            // 2.1) check if a provided recommended version matches as_of_version
            util::get_property_value_for_version(name, values, &as_of_version)?;

            for val in values {
                // 2.2) check if recommended matches the allowed values
                check_allowed_values(name, &val.value, &spec.allowed_values)?;
                // 2.3) check if recommended values match datatype (min, max, unit...)
                check_datatype(&config_spec.units, name, &val.value, &spec.datatype)?
            }
        }

        // prepare "user" data
        let mut user_data = HashMap::new();
        if let Some(dependencies) = &spec.depends_on {
            for dependency in dependencies {
                for dep_name in &dependency.property_names {
                    if let Some(dependency_property) = property_spec.get(dep_name) {
                        if let Some(dependency_property_recommended) =
                            &dependency_property.recommended_values
                        {
                            let filtered_value = util::get_property_value_for_version(
                                &dep_name,
                                dependency_property_recommended,
                                &as_of_version,
                            )?;

                            user_data.insert(dep_name.name.clone(), filtered_value.value.clone());
                        }
                    } else {
                        return Err(Error::PropertyDependencyMissing {
                            property_name: name.clone(),
                            dependency: dependency.property_names.clone(),
                        });
                    }
                }
            }
        }
        // 3) check if dependency values are available and the recommended value matches the required one
        check_dependencies(name, spec, &user_data)?;

        // 4) check if role available
        if spec.roles.is_none() {
            return Err(Error::PropertySpecRoleNotProvided { name: name.clone() });
        }
    }

    Ok(())
}
/// Check if the provided property spec is correct. Checks include:
/// - if default / recommended values match version, min / max, datatype, unit and regex
/// - if default / recommended values match allowed values if available
/// - if dependencies and required values match recommended values of that dependency
/// - if roles are available
///
/// # Arguments
/// * `config_spec` - map with unit name and respective regular expression to evaluate the datatype
/// * `property_spec` - map with property name as key and the corresponding property spec as value
///
Check if the provided property spec is correct. Checks include:
if default / recommended values match version, min / max, datatype, unit and regex
if default / recommended values match allowed values if available
if dependencies and required values match recommended values of that dependency
if roles are available
Check if the provided property spec is correct . Checks include : if default / recommended values match version min / max datatype unit and regex if default / recommended values match allowed values if available if dependencies and required values match recommended values of that dependency if roles are available
pub(crate) fn validate_property_spec(
    config_spec: &ProductConfigSpecProperties,
    property_spec: &HashMap<PropertyName, PropertySpec>,
) -> ValidationResult<()> {
    for (name, spec) in property_spec {
        let as_of_version = Version::parse(&spec.as_of_version)?;
        // 1) check for default values
        if let Some(values) = &spec.default_values {
            // 1.1) check if a provided default version matches as_of_version
            util::get_property_value_for_version(name, values, &as_of_version)?;
            for val in values {
                // 1.2) check if default matches the allowed values
                check_allowed_values(name, &val.value, &spec.allowed_values)?;
                // 1.3) check if default values match datatype (min, max, unit...)
                check_datatype(&config_spec.units, name, &val.value, &spec.datatype)?
            }
        }
        // 2) check for recommended values
        if let Some(values) = &spec.recommended_values {
            // 2.1) check if a provided recommended version matches as_of_version
            util::get_property_value_for_version(name, values, &as_of_version)?;
            for val in values {
                // 2.2) check if recommended matches the allowed values
                check_allowed_values(name, &val.value, &spec.allowed_values)?;
                // 2.3) check if recommended values match datatype (min, max, unit...)
                check_datatype(&config_spec.units, name, &val.value, &spec.datatype)?
            }
        }
        // prepare "user" data
        let mut user_data = HashMap::new();
        if let Some(dependencies) = &spec.depends_on {
            for dependency in dependencies {
                for dep_name in &dependency.property_names {
                    if let Some(dependency_property) = property_spec.get(dep_name) {
                        if let Some(dependency_property_recommended) =
                            &dependency_property.recommended_values
                        {
                            let filtered_value = util::get_property_value_for_version(
                                &dep_name,
                                dependency_property_recommended,
                                &as_of_version,
                            )?;
                            user_data.insert(dep_name.name.clone(), filtered_value.value.clone());
                        }
                    } else {
                        return Err(Error::PropertyDependencyMissing {
                            property_name: name.clone(),
                            dependency: dependency.property_names.clone(),
                        });
                    }
                }
            }
        }
        // 3) check if dependency values are available and the recommended value matches the required one
        check_dependencies(name, spec, &user_data)?;
        // 4) check if role available
        if spec.roles.is_none() {
            return Err(Error::PropertySpecRoleNotProvided { name: name.clone() });
        }
    }
    Ok(())
}
pub ( crate ) fn validate_property_spec ( config_spec : & ProductConfigSpecProperties , property_spec : & HashMap < PropertyName , PropertySpec > , ) -> ValidationResult < ( ) > { for ( name , spec ) in property_spec { let as_of_version = Version :: parse ( & spec . as_of_version ) ? ; // 1) check for default values if let Some ( values ) = & spec . default_values { // 1.1) check if a provided default version matches as_of_version util :: get_property_value_for_version ( name , values , & as_of_version ) ? ; for val in values { // 1.2) check if default matches the allowed values check_allowed_values ( name , & val . value , & spec . allowed_values ) ? ; // 1.3) check if default values match datatype (min, max, unit...) check_datatype ( & config_spec . units , name , & val . value , & spec . datatype ) ? } } // 2) check for recommended values if let Some ( values ) = & spec . recommended_values { // 2.1) check if a provided recommended version matches as_of_version util :: get_property_value_for_version ( name , values , & as_of_version ) ? ; for val in values { // 2.2) check if recommended matches the allowed values check_allowed_values ( name , & val . value , & spec . allowed_values ) ? ; // 2.3) check if recommended values match datatype (min, max, unit...) check_datatype ( & config_spec . units , name , & val . value , & spec . datatype ) ? } } // prepare "user" data let mut user_data = HashMap :: new ( ) ; if let Some ( dependencies ) = & spec . depends_on { for dependency in dependencies { for dep_name in & dependency . property_names { if let Some ( dependency_property ) = property_spec . get ( dep_name ) { if let Some ( dependency_property_recommended ) = & dependency_property . recommended_values { let filtered_value = util :: get_property_value_for_version ( & dep_name , dependency_property_recommended , & as_of_version , ) ? ; user_data . insert ( dep_name . name . clone ( ) , filtered_value . value . clone ( ) ) ; } } else { return Err ( Error :: PropertyDependencyMissing { property_name : name . clone ( ) , dependency : dependency . property_names . clone ( ) , } ) ; } } } } // 3) check if dependency values are available and the recommended value matches the required one check_dependencies ( name , spec , & user_data ) ? ; // 4) check if role available if spec . roles . is_none ( ) { return Err ( Error :: PropertySpecRoleNotProvided { name : name . clone ( ) } ) ; } } Ok ( ( ) ) }
Check if the provided property spec is correct.
Check if the provided property spec is correct .
config_spec
&ProductConfigSpecProperties
property_spec
&HashMap<PropertyName, PropertySpec>