Skip to main content

knowledge_base_validation/
additional_validator.rs

1use crate::{Diagnostic, diagnostic, validator};
2use std::path::Path;
3
4/// A domain-specific, read-only validator for a complete knowledge-base repository.
5///
6/// Diagnostics must use paths relative to `repository`, so they remain meaningful when
7/// mutations validate a temporary staged copy.
8pub trait AdditionalValidator: Send + Sync {
9    fn validate(&self, repository: &Path) -> Vec<Diagnostic>;
10}
11
12impl<F> AdditionalValidator for F
13where
14    F: Fn(&Path) -> Vec<Diagnostic> + Send + Sync,
15{
16    fn validate(&self, repository: &Path) -> Vec<Diagnostic> {
17        self(repository)
18    }
19}
20
21/// Validates a repository with the built-in rules followed by every supplied domain validator.
22///
23/// All validators run even when another validator reports diagnostics. The returned diagnostics
24/// are sorted deterministically by path, line, identifier, message, and validation layer.
25pub fn validate_repository_with<'a>(root: impl AsRef<Path>, validators: impl IntoIterator<Item = &'a dyn AdditionalValidator>) -> Vec<Diagnostic> {
26    let root = root.as_ref();
27    let mut diagnostics = validator::validate_repository(root);
28    for validator in validators {
29        diagnostics.extend(validator.validate(root));
30    }
31    diagnostic::sort_diagnostics(&mut diagnostics);
32    diagnostics
33}