use crate::domain::model::check::{
extract_id_prefix_from_path, id_prefix_matches, CheckViolationKind, Severity,
};
use crate::domain::usecases::check::{CheckViolation, IssueCheckCtx, IssueFinding, IssueRule};
pub struct IdMatchesDirectoryRule;
pub const RULE_ID: &str = "issue/id-matches-directory";
impl IssueRule for IdMatchesDirectoryRule {
fn id(&self) -> &'static str {
RULE_ID
}
fn find(&self, ctx: &IssueCheckCtx<'_>) -> anyhow::Result<Vec<IssueFinding>> {
let mut out = Vec::new();
for (path, issue) in ctx.issues {
let parent = path.parent().unwrap_or(path);
let Some(dir_prefix) = extract_id_prefix_from_path(parent) else {
continue;
};
let id_suffix = issue.id.suffix();
if id_prefix_matches(&dir_prefix, id_suffix) {
continue;
}
let kind = CheckViolationKind::IdSlugMismatch {
id_suffix: id_suffix.to_string(),
dir_prefix: dir_prefix.clone(),
};
out.push(CheckViolation {
rule_id: RULE_ID,
path: path.clone(),
severity: Severity::Error,
kind,
});
}
Ok(out.into_iter().map(IssueFinding::report).collect())
}
}