1use async_trait::async_trait;
7use serde::{Deserialize, Serialize};
8
9use super::error::HopeResult;
10use super::identity::{CodeIdentity, ModuleState};
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct Reflection {
15 pub name: String,
17 pub purpose: String,
19 pub state: String,
21 pub health: f64,
23 pub thoughts: Vec<String>,
25 pub capabilities: Vec<String>,
27}
28
29impl Reflection {
30 pub fn new(name: impl Into<String>, purpose: impl Into<String>) -> Self {
32 Self {
33 name: name.into(),
34 purpose: purpose.into(),
35 state: "unknown".to_string(),
36 health: 1.0,
37 thoughts: Vec::new(),
38 capabilities: Vec::new(),
39 }
40 }
41
42 pub fn with_state(mut self, state: impl Into<String>) -> Self {
44 self.state = state.into();
45 self
46 }
47
48 pub fn with_health(mut self, health: f64) -> Self {
50 self.health = health.clamp(0.0, 1.0);
51 self
52 }
53
54 pub fn with_thought(mut self, thought: impl Into<String>) -> Self {
56 self.thoughts.push(thought.into());
57 self
58 }
59
60 pub fn with_thoughts(mut self, thoughts: Vec<&str>) -> Self {
62 self.thoughts.extend(thoughts.into_iter().map(String::from));
63 self
64 }
65
66 pub fn with_capability(mut self, cap: impl Into<String>) -> Self {
68 self.capabilities.push(cap.into());
69 self
70 }
71
72 pub fn with_capabilities(mut self, caps: Vec<&str>) -> Self {
74 self.capabilities.extend(caps.into_iter().map(String::from));
75 self
76 }
77
78 pub fn to_text(&self) -> String {
80 let mut text = format!(
81 "╔═══ {} ═══╗\n║ Cél: {}\n║ Állapot: {}\n║ Egészség: {:.1}%\n",
82 self.name,
83 self.purpose,
84 self.state,
85 self.health * 100.0
86 );
87
88 if !self.thoughts.is_empty() {
89 text.push_str("║ Gondolatok:\n");
90 for thought in &self.thoughts {
91 text.push_str(&format!("║ - {}\n", thought));
92 }
93 }
94
95 if !self.capabilities.is_empty() {
96 text.push_str("║ Képességek:\n");
97 for cap in &self.capabilities {
98 text.push_str(&format!("║ • {}\n", cap));
99 }
100 }
101
102 text.push_str("╚════════════════════════════════╝");
103 text
104 }
105}
106
107impl std::fmt::Display for Reflection {
108 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109 write!(f, "{}", self.to_text())
110 }
111}
112
113#[async_trait]
121pub trait Aware: Send + Sync {
122 fn identity(&self) -> &CodeIdentity;
124
125 fn identity_mut(&mut self) -> &mut CodeIdentity;
127
128 fn introduce(&self) -> String {
130 self.identity().introduce()
131 }
132
133 fn state(&self) -> ModuleState {
135 self.identity().state
136 }
137
138 fn reflect(&self) -> Reflection {
140 let identity = self.identity();
141 Reflection::new(&identity.name, &identity.purpose)
142 .with_state(identity.state.to_string())
143 .with_health(identity.health())
144 .with_capabilities(identity.capabilities.iter().map(|s| s.as_str()).collect())
145 }
146
147 fn name(&self) -> &str {
149 &self.identity().name
150 }
151
152 async fn init(&mut self) -> HopeResult<()> {
154 self.identity_mut().set_state(ModuleState::Active);
155 Ok(())
156 }
157
158 async fn shutdown(&mut self) -> HopeResult<()> {
160 self.identity_mut().set_state(ModuleState::Shutdown);
161 Ok(())
162 }
163
164 fn activate(&mut self) {
166 self.identity_mut().set_state(ModuleState::Active);
167 }
168
169 fn deactivate(&mut self) {
171 self.identity_mut().set_state(ModuleState::Idle);
172 }
173
174 fn set_error(&mut self) {
176 self.identity_mut().set_state(ModuleState::Error);
177 }
178
179 fn set_busy(&mut self) {
181 self.identity_mut().set_state(ModuleState::Busy);
182 }
183}
184
185#[macro_export]
187macro_rules! impl_aware {
188 ($type:ty, $identity_field:ident) => {
189 impl $crate::core::aware::Aware for $type {
190 fn identity(&self) -> &$crate::core::identity::CodeIdentity {
191 &self.$identity_field
192 }
193
194 fn identity_mut(&mut self) -> &mut $crate::core::identity::CodeIdentity {
195 &mut self.$identity_field
196 }
197 }
198 };
199}
200
201#[cfg(test)]
202mod tests {
203 use super::*;
204 use crate::core::identity::ModuleType;
205
206 struct TestModule {
207 identity: CodeIdentity,
208 }
209
210 impl TestModule {
211 fn new() -> Self {
212 Self {
213 identity: CodeIdentity::new("TestModule", "Tesztelés", ModuleType::Module),
214 }
215 }
216 }
217
218 #[async_trait]
219 impl Aware for TestModule {
220 fn identity(&self) -> &CodeIdentity {
221 &self.identity
222 }
223
224 fn identity_mut(&mut self) -> &mut CodeIdentity {
225 &mut self.identity
226 }
227 }
228
229 #[test]
230 fn test_reflection() {
231 let reflection = Reflection::new("Test", "Testing")
232 .with_state("Active")
233 .with_health(0.95)
234 .with_thought("All systems go");
235
236 assert_eq!(reflection.name, "Test");
237 assert_eq!(reflection.health, 0.95);
238 assert_eq!(reflection.thoughts.len(), 1);
239 }
240
241 #[tokio::test]
242 async fn test_aware_trait() {
243 let mut module = TestModule::new();
244 assert_eq!(module.state(), ModuleState::Initializing);
245
246 module.init().await.unwrap();
247 assert_eq!(module.state(), ModuleState::Active);
248
249 module.shutdown().await.unwrap();
250 assert_eq!(module.state(), ModuleState::Shutdown);
251 }
252}