1use std::any::Any;
13use std::collections::HashMap;
14use std::fmt::Debug;
15use std::sync::{Arc, RwLock};
16
17#[derive(Debug, Clone)]
19pub struct RegistryError {
20 message: String,
21}
22
23impl RegistryError {
24 pub fn new(message: &str) -> Self {
26 RegistryError {
27 message: message.to_string(),
28 }
29 }
30}
31
32impl std::fmt::Display for RegistryError {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 write!(f, "Registry error: {}", self.message)
35 }
36}
37
38impl std::error::Error for RegistryError {}
39
40pub trait ComponentRegistry: Send + Sync {
46 fn register<T: 'static + Send + Sync>(&mut self, name: &str, component: Arc<RwLock<T>>) -> Result<(), RegistryError>;
48
49 fn get<T: 'static + Send + Sync>(&self, name: &str) -> Option<Arc<RwLock<T>>>;
51
52 fn get_mut<T: 'static + Send + Sync>(&self, name: &str) -> Option<Arc<RwLock<T>>>;
58
59 fn contains(&self, name: &str) -> bool;
61}
62
63pub struct HTTComponentRegistry {
65 components: HashMap<String, Arc<RwLock<Box<dyn Any + Send + Sync>>>>,
66}
67
68impl Debug for HTTComponentRegistry {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 f.debug_struct("HTTComponentRegistry")
71 .field("components_count", &self.components.len())
72 .finish()
73 }
74}
75
76impl HTTComponentRegistry {
77 pub fn new() -> Self {
79 HTTComponentRegistry {
80 components: HashMap::new(),
81 }
82 }
83
84 pub fn len(&self) -> usize {
86 self.components.len()
87 }
88
89 pub fn is_empty(&self) -> bool {
91 self.components.is_empty()
92 }
93}
94
95impl ComponentRegistry for HTTComponentRegistry {
96 fn register<T: 'static + Send + Sync>(&mut self, name: &str, component: Arc<RwLock<T>>) -> Result<(), RegistryError> {
97 let boxed: Box<dyn Any + Send + Sync> = Box::new(component);
99 self.components.insert(name.to_string(), Arc::new(RwLock::new(boxed)));
100 Ok(())
101 }
102
103 fn get<T: 'static + Send + Sync>(&self, name: &str) -> Option<Arc<RwLock<T>>> {
104 self.components.get(name).and_then(|boxed_any| {
105 let guard = boxed_any.read().ok()?;
106 guard.downcast_ref::<Arc<RwLock<T>>>().cloned()
107 })
108 }
109
110 fn get_mut<T: 'static + Send + Sync>(&self, name: &str) -> Option<Arc<RwLock<T>>> {
111 self.get(name)
113 }
114
115 fn contains(&self, name: &str) -> bool {
116 self.components.contains_key(name)
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[derive(Debug)]
126 struct TestComponent {
127 value: i32,
128 }
129
130 #[test]
131 fn test_registry_operations() {
132 let mut registry = HTTComponentRegistry::new();
134
135 let component = Arc::new(RwLock::new(TestComponent { value: 42 }));
137 registry.register("test", component).unwrap();
138
139 assert!(registry.contains("test"));
141 assert!(!registry.contains("nonexistent"));
142
143 let retrieved = registry.get::<TestComponent>("test").unwrap();
145 assert_eq!(retrieved.read().unwrap().value, 42);
146
147 {
149 let mut comp = retrieved.write().unwrap();
150 comp.value = 100;
151 }
152
153 let retrieved_again = registry.get::<TestComponent>("test").unwrap();
155 assert_eq!(retrieved_again.read().unwrap().value, 100);
156 }
157
158 #[test]
159 fn test_multiple_components() {
160 let mut registry = HTTComponentRegistry::new();
162
163 registry.register("comp1", Arc::new(RwLock::new(TestComponent { value: 1 }))).unwrap();
165 registry.register("comp2", Arc::new(RwLock::new(TestComponent { value: 2 }))).unwrap();
166 registry.register("comp3", Arc::new(RwLock::new(TestComponent { value: 3 }))).unwrap();
167
168 assert_eq!(registry.len(), 3);
170
171 let comp1 = registry.get::<TestComponent>("comp1").unwrap();
173 let comp2 = registry.get::<TestComponent>("comp2").unwrap();
174 let comp3 = registry.get::<TestComponent>("comp3").unwrap();
175
176 assert_eq!(comp1.read().unwrap().value, 1);
178 assert_eq!(comp2.read().unwrap().value, 2);
179 assert_eq!(comp3.read().unwrap().value, 3);
180 }
181}