use std::collections::HashMap;
use crate::adapters::analyzers::coupling::CouplingAnalysis;
use crate::adapters::shared::file_to_module::file_to_module;
use crate::findings::{Dimension, Suppression};
pub(crate) struct ModuleCouplingSuppressions {
by_module: HashMap<String, Vec<Suppression>>,
}
impl ModuleCouplingSuppressions {
pub(crate) fn build(suppression_lines: &HashMap<String, Vec<Suppression>>) -> Self {
let mut by_module: HashMap<String, Vec<Suppression>> = HashMap::new();
suppression_lines.iter().for_each(|(path, sups)| {
let module = file_to_module(path);
sups.iter()
.filter(|s| s.covers(Dimension::Coupling))
.for_each(|s| {
by_module.entry(module.clone()).or_default().push(s.clone());
});
});
Self { by_module }
}
pub(crate) fn blanket(&self, module: &str) -> bool {
self.by_module
.get(module)
.is_some_and(|v| v.iter().any(|s| s.target.is_none()))
}
pub(crate) fn suppresses(&self, module: &str, target: &str, value: Option<f64>) -> bool {
self.by_module.get(module).is_some_and(|v| {
v.iter()
.any(|s| s.suppresses(Dimension::Coupling, target, value))
})
}
}
pub(crate) fn mark_coupling_blanket(
analysis: Option<&mut CouplingAnalysis>,
sups: &ModuleCouplingSuppressions,
) {
let Some(analysis) = analysis else { return };
analysis.metrics.iter_mut().for_each(|m| {
if sups.blanket(&m.module_name) {
m.suppressed = true;
}
});
}
pub(crate) fn mark_sdp_target_suppressions(
analysis: &mut CouplingAnalysis,
sups: &ModuleCouplingSuppressions,
) {
analysis.sdp_violations.iter_mut().for_each(|v| {
if sups.suppresses(&v.from_module, "sdp", None)
|| sups.suppresses(&v.to_module, "sdp", None)
{
v.suppressed = true;
}
});
}