cha_core/plugins/
data_class.rs1use crate::{AnalysisContext, Finding, Location, Plugin, Severity, SmellCategory};
2
3pub struct DataClassAnalyzer {
5 pub min_fields: usize,
6}
7
8impl Default for DataClassAnalyzer {
9 fn default() -> Self {
10 Self { min_fields: 2 }
11 }
12}
13
14impl Plugin for DataClassAnalyzer {
15 fn name(&self) -> &str {
16 "data_class"
17 }
18
19 fn description(&self) -> &str {
20 "Class with only data, no behavior"
21 }
22
23 fn analyze(&self, ctx: &AnalysisContext) -> Vec<Finding> {
24 ctx.model
25 .classes
26 .iter()
27 .filter_map(|c| {
28 if c.is_interface || c.field_count < self.min_fields || c.has_behavior {
29 return None;
30 }
31 Some(Finding {
32 smell_name: "data_class".into(),
33 category: SmellCategory::Dispensables,
34 severity: Severity::Hint,
35 location: Location {
36 path: ctx.file.path.clone(),
37 start_line: c.start_line,
38 end_line: c.end_line,
39 name: Some(c.name.clone()),
40 },
41 message: format!(
42 "Class `{}` has {} fields but no behavior methods, consider Move Method",
43 c.name, c.field_count
44 ),
45 suggested_refactorings: vec!["Move Method".into(), "Encapsulate Field".into()],
46 ..Default::default()
47 })
48 })
49 .collect()
50 }
51}