dei_core/
models.rs

1//! Analysis result models
2
3use serde::{Deserialize, Serialize};
4use std::sync::Arc;
5use std::time::SystemTime;
6
7use crate::metrics::*;
8
9/// Represents a cluster of methods with shared responsibility
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct ResponsibilityCluster {
12    pub suggested_name: Arc<str>,
13    pub methods: Arc<[Arc<str>]>, // Method names
14    pub cohesion_score: f64,
15    pub shared_dependencies: Arc<[Arc<str>]>,
16    pub justification: Arc<str>,
17}
18
19/// Analysis result for a god method
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct GodMethodResult {
22    pub method_name: Arc<str>,
23    pub class_name: Arc<str>,
24    pub file_path: Arc<str>,
25    pub metrics: MethodMetrics,
26    pub violations: Arc<[Violation]>,
27    pub violation_score: f64,
28}
29
30/// Analysis result for a god file
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct GodFileResult {
33    pub file_path: Arc<str>,
34    pub class_count: usize,
35    pub total_lines: usize,
36    pub class_names: Arc<[Arc<str>]>,
37    pub violations: Arc<[Violation]>,
38}
39
40/// Specific threshold violation
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct Violation {
43    pub kind: ViolationKind,
44    pub actual: usize,
45    pub threshold: usize,
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
49pub enum ViolationKind {
50    Lines,
51    Complexity,
52    MethodCount,
53    ParameterCount,
54    ClassesPerFile,
55}
56
57/// Complete analysis result for a class
58#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct AnalysisResult {
60    pub class_metrics: ClassMetrics,
61    pub is_god_class: bool,
62    pub suggested_extractions: Arc<[ResponsibilityCluster]>,
63    pub god_methods: Arc<[GodMethodResult]>,
64    #[serde(skip_serializing, default = "default_systemtime")]
65    pub analyzed_at: SystemTime,
66    pub summary: Arc<str>,
67}
68
69fn default_systemtime() -> SystemTime {
70    SystemTime::now()
71}
72
73impl AnalysisResult {
74    pub fn healthy(metrics: ClassMetrics) -> Self {
75        Self {
76            summary: format!("Class '{}' is within acceptable thresholds", metrics.name).into(),
77            class_metrics: metrics,
78            is_god_class: false,
79            suggested_extractions: Arc::new([]),
80            god_methods: Arc::new([]),
81            analyzed_at: SystemTime::now(),
82        }
83    }
84
85    pub fn has_issues(&self) -> bool {
86        self.is_god_class || !self.god_methods.is_empty()
87    }
88}
89
90/// Language being analyzed
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
92pub enum Language {
93    Rust,
94    CSharp,
95    Python,
96    JavaScript,
97    TypeScript,
98    Go,
99    Java,
100}
101
102impl Language {
103    pub fn from_extension(ext: &str) -> Option<Self> {
104        match ext {
105            "rs" => Some(Language::Rust),
106            "cs" => Some(Language::CSharp),
107            "py" => Some(Language::Python),
108            "js" => Some(Language::JavaScript),
109            "ts" => Some(Language::TypeScript),
110            "go" => Some(Language::Go),
111            "java" => Some(Language::Java),
112            _ => None,
113        }
114    }
115
116    pub fn extensions(&self) -> &[&str] {
117        match self {
118            Language::Rust => &["rs"],
119            Language::CSharp => &["cs"],
120            Language::Python => &["py"],
121            Language::JavaScript => &["js"],
122            Language::TypeScript => &["ts"],
123            Language::Go => &["go"],
124            Language::Java => &["java"],
125        }
126    }
127}
128