cha_core/plugins/
hub_like.rs1use crate::{AnalysisContext, Finding, Location, Plugin, Severity, SmellCategory};
2
3pub struct HubLikeDependencyAnalyzer {
19 pub max_imports: usize,
20}
21
22impl Default for HubLikeDependencyAnalyzer {
23 fn default() -> Self {
24 Self { max_imports: 20 }
25 }
26}
27
28impl Plugin for HubLikeDependencyAnalyzer {
29 fn name(&self) -> &str {
30 "hub_like_dependency"
31 }
32
33 fn description(&self) -> &str {
34 "Hub-like module with too many imports"
35 }
36
37 fn analyze(&self, ctx: &AnalysisContext) -> Vec<Finding> {
38 let count = ctx
39 .model
40 .imports
41 .iter()
42 .filter(|i| !i.is_module_decl)
43 .count();
44 if count <= self.max_imports {
45 return vec![];
46 }
47 vec![Finding {
48 smell_name: "hub_like_dependency".into(),
49 category: SmellCategory::Couplers,
50 severity: Severity::Warning,
51 location: Location {
52 path: ctx.file.path.clone(),
53 start_line: 1,
54 end_line: ctx.model.total_lines,
55 name: None,
56 },
57 message: format!(
58 "File has {} imports (threshold: {}), acting as a hub — consider splitting",
59 count, self.max_imports
60 ),
61 suggested_refactorings: vec!["Extract Module".into(), "Facade Pattern".into()],
62 actual_value: Some(count as f64),
63 threshold: Some(self.max_imports as f64),
64 }]
65 }
66}