tier 0.1.17

Rust configuration library for layered TOML, env, and CLI settings
Documentation
use std::collections::BTreeSet;

use serde_json::Value;

use crate::error::ValidationErrors;
use crate::metadata::ConfigMetadata;
use crate::path::get_value_at_path;
use crate::report::{ConfigReport, ConfigWarning};

mod checks;
mod error;
mod matching;
mod rules;

use self::matching::collect_matching_values;
use self::rules::validate_declared_rule;

pub(super) fn validate_declared_rules(
    value: &Value,
    metadata: &ConfigMetadata,
    secret_paths: &BTreeSet<String>,
    report: &mut ConfigReport,
) -> ValidationErrors {
    let mut errors = ValidationErrors::new();
    let mut matched_paths = BTreeSet::<String>::new();

    for field in metadata.fields() {
        if field.validations.is_empty() || field.path.is_empty() {
            continue;
        }
        matched_paths.extend(
            collect_matching_values(value, &field.path)
                .into_iter()
                .map(|(matched_path, _)| matched_path),
        );
    }

    for matched_path in matched_paths {
        let Some(actual) = get_value_at_path(value, &matched_path) else {
            continue;
        };
        for effective in metadata.effective_validations_for(&matched_path) {
            let rule = &effective.rule;
            let field = effective.field;
            if let Some(error) = validate_declared_rule(&matched_path, actual, rule, secret_paths) {
                let error = field.decorate_validation_error(rule, error);
                match field.validation_level_for(rule) {
                    crate::ValidationLevel::Error => errors.push(error),
                    crate::ValidationLevel::Warning => {
                        report.record_warning(ConfigWarning::Validation(error));
                    }
                }
            }
        }
    }

    errors
}

pub(super) fn validate_declared_checks(
    value: &Value,
    metadata: &ConfigMetadata,
    secret_paths: &BTreeSet<String>,
) -> ValidationErrors {
    checks::validate_declared_checks(value, metadata, secret_paths)
}