use crate::domain::model::check::{CheckViolationKind, Severity};
use crate::domain::usecases::check::{CheckViolation, IssueCheckCtx, IssueFinding, IssueRule};
pub struct UnknownLinkTargetRule;
pub const RULE_ID: &str = "issue/unknown-link-target";
impl IssueRule for UnknownLinkTargetRule {
fn id(&self) -> &'static str {
RULE_ID
}
fn find(&self, ctx: &IssueCheckCtx<'_>) -> anyhow::Result<Vec<IssueFinding>> {
if ctx.known_refs.is_empty() {
return Ok(Vec::new());
}
let mut out = Vec::new();
for (path, issue) in ctx.issues {
for link in issue.links.iter() {
if !ctx.known_refs.contains(link.target.as_entity_ref()) {
let kind = CheckViolationKind::LinkTargetNotFound {
target: link.target.as_entity_ref().clone(),
};
out.push(CheckViolation {
rule_id: RULE_ID,
path: path.clone(),
severity: Severity::Warning,
kind,
});
}
}
for target in issue.relates().iter() {
if !ctx.known_refs.contains(target) {
let kind = CheckViolationKind::LinkTargetNotFound {
target: target.clone(),
};
out.push(CheckViolation {
rule_id: RULE_ID,
path: path.clone(),
severity: Severity::Warning,
kind,
});
}
}
}
Ok(out.into_iter().map(IssueFinding::report).collect())
}
}