1use serde::{Deserialize, Serialize};
4use std::sync::Arc;
5use std::time::SystemTime;
6
7use crate::metrics::*;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct ResponsibilityCluster {
12 pub suggested_name: Arc<str>,
13 pub methods: Arc<[Arc<str>]>, pub cohesion_score: f64,
15 pub shared_dependencies: Arc<[Arc<str>]>,
16 pub justification: Arc<str>,
17}
18
19#[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#[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#[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#[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#[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