xbp_analysis/application/rules/
placeholder.rs1use super::{base_caps, concepts_of, finding_from_concept};
2use crate::domain::concepts::ConceptKind;
3use crate::domain::model::LanguageModel;
4use crate::domain::rule::{Rule, RuleMeta};
5use crate::domain::types::{Confidence, Finding, Severity};
6use std::sync::OnceLock;
7
8#[derive(Default)]
9pub struct PlaceholderHandlerRule;
10
11impl Rule for PlaceholderHandlerRule {
12 fn meta(&self) -> &RuleMeta {
13 static META: OnceLock<RuleMeta> = OnceLock::new();
14 META.get_or_init(|| RuleMeta {
15 id: "placeholder-handler".into(),
16 name: "Placeholder in critical path".into(),
17 description: "TODO/FIXME/todo!/unimplemented! on an error path.".into(),
18 default_severity: Severity::High,
19 required_capabilities: base_caps(),
20 autofix_safe: false,
21 })
22 }
23
24 fn evaluate(&self, model: &LanguageModel) -> Vec<Finding> {
25 concepts_of(model, ConceptKind::Placeholder)
26 .map(|(lang, c)| {
27 let sev = if c.critical_path {
28 Severity::Critical
29 } else {
30 Severity::High
31 };
32 finding_from_concept(
33 &self.meta().id,
34 lang,
35 c,
36 sev,
37 Confidence::High,
38 "Placeholder remains on a failure path.",
39 "Production hits unfinished error handling and aborts or no-ops.",
40 "Implement the handler or fail closed with a structured error.",
41 )
42 })
43 .collect()
44 }
45}