Skip to main content

cha_core/plugins/
coupling.rs

1use crate::{AnalysisContext, Finding, Location, Plugin, Severity, SmellCategory};
2
3/// Detect high coupling via excessive imports.
4pub struct CouplingAnalyzer {
5    pub max_imports: usize,
6}
7
8impl Default for CouplingAnalyzer {
9    fn default() -> Self {
10        Self { max_imports: 15 }
11    }
12}
13
14impl Plugin for CouplingAnalyzer {
15    fn name(&self) -> &str {
16        "coupling"
17    }
18
19    fn description(&self) -> &str {
20        "Too many imports (high coupling)"
21    }
22
23    fn analyze(&self, ctx: &AnalysisContext) -> Vec<Finding> {
24        let mut findings = Vec::new();
25
26        // Skip Rust mod declarations — module organization, not coupling
27        // Skip module declarations — module organization, not coupling
28        let import_count = ctx
29            .model
30            .imports
31            .iter()
32            .filter(|i| !i.is_module_decl)
33            .count();
34
35        if import_count > self.max_imports {
36            findings.push(Finding {
37                smell_name: "high_coupling".into(),
38                category: SmellCategory::Couplers,
39                severity: if import_count > self.max_imports * 2 {
40                    Severity::Error
41                } else {
42                    Severity::Warning
43                },
44                location: Location {
45                    path: ctx.file.path.clone(),
46                    start_line: 1,
47                    end_line: ctx.model.total_lines,
48                    name: None,
49                },
50                message: format!(
51                    "File has {} imports (threshold: {})",
52                    import_count, self.max_imports
53                ),
54                suggested_refactorings: vec!["Move Method".into(), "Extract Class".into()],
55                actual_value: Some(import_count as f64),
56                threshold: Some(self.max_imports as f64),
57            });
58        }
59
60        findings
61    }
62}