1use chrono::{DateTime, Utc};
7use serde::{Deserialize, Serialize};
8use std::fmt;
9use uuid::Uuid;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
13pub enum ModuleType {
14 Core,
16 Module,
18 Service,
20 Agent,
22 Data,
24}
25
26impl fmt::Display for ModuleType {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 match self {
29 ModuleType::Core => write!(f, "Core"),
30 ModuleType::Module => write!(f, "Module"),
31 ModuleType::Service => write!(f, "Service"),
32 ModuleType::Agent => write!(f, "Agent"),
33 ModuleType::Data => write!(f, "Data"),
34 }
35 }
36}
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
40pub enum ModuleState {
41 Initializing,
43 Active,
45 Idle,
47 Busy,
49 Sleeping,
51 Error,
53 Shutdown,
55}
56
57impl ModuleState {
58 pub fn emoji(&self) -> &'static str {
60 match self {
61 ModuleState::Initializing => "⏳",
62 ModuleState::Active => "🟢",
63 ModuleState::Idle => "💤",
64 ModuleState::Busy => "🔄",
65 ModuleState::Sleeping => "😴",
66 ModuleState::Error => "🔴",
67 ModuleState::Shutdown => "⭕",
68 }
69 }
70
71 pub fn description_hu(&self) -> &'static str {
73 match self {
74 ModuleState::Initializing => "Inicializálás",
75 ModuleState::Active => "Aktív",
76 ModuleState::Idle => "Tétlen",
77 ModuleState::Busy => "Dolgozik",
78 ModuleState::Sleeping => "Alszik",
79 ModuleState::Error => "Hiba",
80 ModuleState::Shutdown => "Leállt",
81 }
82 }
83}
84
85impl fmt::Display for ModuleState {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 write!(f, "{} {}", self.emoji(), self.description_hu())
88 }
89}
90
91#[derive(Debug, Clone, Default, Serialize, Deserialize)]
93pub struct ModuleStats {
94 pub calls: u64,
96 pub successes: u64,
98 pub errors: u64,
100 pub total_response_time_ms: u64,
102 pub last_call: Option<DateTime<Utc>>,
104}
105
106impl ModuleStats {
107 pub fn new() -> Self {
109 Self::default()
110 }
111
112 pub fn record_success(&mut self, response_time_ms: u64) {
114 self.calls += 1;
115 self.successes += 1;
116 self.total_response_time_ms += response_time_ms;
117 self.last_call = Some(Utc::now());
118 }
119
120 pub fn record_error(&mut self) {
122 self.calls += 1;
123 self.errors += 1;
124 self.last_call = Some(Utc::now());
125 }
126
127 pub fn avg_response_time_ms(&self) -> f64 {
129 if self.successes == 0 {
130 0.0
131 } else {
132 self.total_response_time_ms as f64 / self.successes as f64
133 }
134 }
135
136 pub fn success_rate(&self) -> f64 {
138 if self.calls == 0 {
139 1.0
140 } else {
141 self.successes as f64 / self.calls as f64
142 }
143 }
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
148pub struct CodeIdentity {
149 pub id: Uuid,
151 pub name: String,
153 pub purpose: String,
155 pub module_type: ModuleType,
157 pub created_at: DateTime<Utc>,
159 pub version: String,
161 pub dependencies: Vec<String>,
163 pub capabilities: Vec<String>,
165 pub state: ModuleState,
167 pub stats: ModuleStats,
169}
170
171impl CodeIdentity {
172 pub fn new(
174 name: impl Into<String>,
175 purpose: impl Into<String>,
176 module_type: ModuleType,
177 ) -> Self {
178 Self {
179 id: Uuid::new_v4(),
180 name: name.into(),
181 purpose: purpose.into(),
182 module_type,
183 created_at: Utc::now(),
184 version: env!("CARGO_PKG_VERSION").to_string(),
185 dependencies: Vec::new(),
186 capabilities: Vec::new(),
187 state: ModuleState::Initializing,
188 stats: ModuleStats::new(),
189 }
190 }
191
192 pub fn with_dependency(mut self, dep: impl Into<String>) -> Self {
194 self.dependencies.push(dep.into());
195 self
196 }
197
198 pub fn with_capability(mut self, cap: impl Into<String>) -> Self {
200 self.capabilities.push(cap.into());
201 self
202 }
203
204 pub fn with_capabilities(mut self, caps: Vec<&str>) -> Self {
206 self.capabilities.extend(caps.into_iter().map(String::from));
207 self
208 }
209
210 pub fn set_state(&mut self, state: ModuleState) {
212 self.state = state;
213 }
214
215 pub fn introduce(&self) -> String {
217 format!(
218 "{} vagyok ({}). {}",
219 self.name, self.module_type, self.purpose
220 )
221 }
222
223 pub fn age_minutes(&self) -> i64 {
225 let now = Utc::now();
226 (now - self.created_at).num_minutes()
227 }
228
229 pub fn health(&self) -> f64 {
231 match self.state {
232 ModuleState::Active | ModuleState::Idle => {
233 let error_penalty = if self.stats.calls > 0 {
235 self.stats.errors as f64 / self.stats.calls as f64 * 0.5
236 } else {
237 0.0
238 };
239 (1.0 - error_penalty).max(0.0)
240 }
241 ModuleState::Busy => 0.9,
242 ModuleState::Initializing => 0.8,
243 ModuleState::Sleeping => 0.7,
244 ModuleState::Error => 0.3,
245 ModuleState::Shutdown => 0.0,
246 }
247 }
248}
249
250impl fmt::Display for CodeIdentity {
251 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
252 let id_str = self.id.to_string();
253 write!(
254 f,
255 "[{}] {} ({}) - {} - {}",
256 &id_str[..8],
257 self.name,
258 self.module_type,
259 self.state,
260 self.purpose
261 )
262 }
263}
264
265#[cfg(test)]
266mod tests {
267 use super::*;
268
269 #[test]
270 fn test_identity_creation() {
271 let identity = CodeIdentity::new("TestModule", "Tesztelés", ModuleType::Module);
272 assert_eq!(identity.name, "TestModule");
273 assert_eq!(identity.state, ModuleState::Initializing);
274 }
275
276 #[test]
277 fn test_module_state_display() {
278 assert_eq!(ModuleState::Active.to_string(), "🟢 Aktív");
279 assert_eq!(ModuleState::Error.to_string(), "🔴 Hiba");
280 }
281
282 #[test]
283 fn test_stats() {
284 let mut stats = ModuleStats::new();
285 stats.record_success(100);
286 stats.record_success(200);
287 stats.record_error();
288
289 assert_eq!(stats.calls, 3);
290 assert_eq!(stats.successes, 2);
291 assert_eq!(stats.errors, 1);
292 assert_eq!(stats.avg_response_time_ms(), 150.0);
293 }
294}