dynamo_runtime/pipeline/
registry.rs1use std::any::Any;
5use std::collections::HashMap;
6use std::sync::Arc;
7
8#[derive(Debug, Default)]
37pub struct Registry {
38 shared_storage: HashMap<String, Arc<dyn Any + Send + Sync>>, unique_storage: HashMap<String, Box<dyn Any + Send + Sync>>, }
41
42impl Registry {
43 pub fn new() -> Self {
45 Registry {
46 shared_storage: HashMap::new(),
47 unique_storage: HashMap::new(),
48 }
49 }
50
51 pub fn contains_shared(&self, key: &str) -> bool {
53 self.shared_storage.contains_key(key)
54 }
55
56 pub fn insert_shared<K: ToString, U: Send + Sync + 'static>(&mut self, key: K, value: U) {
58 self.shared_storage.insert(
59 key.to_string(),
60 Arc::new(value) as Arc<dyn Any + Send + Sync>,
61 );
62 }
63
64 pub fn get_shared<V: Send + Sync + 'static>(&self, key: &str) -> Result<Arc<V>, String> {
66 self.get_shared_optional(key)?
67 .ok_or_else(|| format!("Shared key not found: {}", key))
68 }
69
70 pub fn get_shared_optional<V: Send + Sync + 'static>(
72 &self,
73 key: &str,
74 ) -> Result<Option<Arc<V>>, String> {
75 let Some(boxed) = self.shared_storage.get(key) else {
76 return Ok(None);
77 };
78 boxed.clone().downcast::<V>().map(Some).map_err(|_| {
79 format!(
80 "Failed to downcast to the requested type for shared key: {}",
81 key
82 )
83 })
84 }
85
86 pub fn contains_unique(&self, key: &str) -> bool {
88 self.unique_storage.contains_key(key)
89 }
90
91 pub fn insert_unique<K: ToString, U: Send + Sync + 'static>(&mut self, key: K, value: U) {
93 self.unique_storage.insert(
94 key.to_string(),
95 Box::new(value) as Box<dyn Any + Send + Sync>,
96 );
97 }
98
99 pub fn take_unique<V: Send + Sync + 'static>(&mut self, key: &str) -> Result<V, String> {
101 match self.unique_storage.remove(key) {
102 Some(boxed) => boxed.downcast::<V>().map(|b| *b).map_err(|_| {
103 format!(
104 "Failed to downcast to the requested type for unique key: {}",
105 key
106 )
107 }),
108 None => Err(format!("Takable key not found: {}", key)),
109 }
110 }
111
112 pub fn clone_unique<V: Clone + Send + Sync + 'static>(&self, key: &str) -> Result<V, String> {
114 match self.unique_storage.get(key) {
115 Some(boxed) => boxed.downcast_ref::<V>().cloned().ok_or_else(|| {
116 format!(
117 "Failed to downcast to the requested type for unique key: {}",
118 key
119 )
120 }),
121 None => Err(format!("Takable key not found: {}", key)),
122 }
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 #[test]
131 fn test_insert_and_get_shared() {
132 let mut registry = Registry::new();
133 registry.insert_shared("shared1", 42);
134 assert_eq!(*registry.get_shared::<i32>("shared1").unwrap(), 42);
135 assert!(registry.get_shared::<f64>("shared1").is_err()); }
137
138 #[test]
139 fn test_get_optional_shared() {
140 let mut registry = Registry::new();
141 assert!(
142 registry
143 .get_shared_optional::<i32>("missing")
144 .unwrap()
145 .is_none()
146 );
147
148 registry.insert_shared("shared1", 42);
149 assert_eq!(
150 *registry
151 .get_shared_optional::<i32>("shared1")
152 .unwrap()
153 .unwrap(),
154 42
155 );
156 assert!(registry.get_shared_optional::<f64>("shared1").is_err());
157 }
158
159 #[test]
160 fn test_insert_and_take_unique() {
161 let mut registry = Registry::new();
162 registry.insert_unique("unique1", "Hello".to_string());
163 assert_eq!(registry.take_unique::<String>("unique1").unwrap(), "Hello");
164 assert!(registry.take_unique::<String>("unique1").is_err()); }
166
167 #[test]
168 fn test_insert_and_clone_then_take_unique() {
169 let mut registry = Registry::new();
170
171 registry.insert_unique("unique2", "World".to_string());
172
173 assert_eq!(registry.clone_unique::<String>("unique2").unwrap(), "World");
174
175 assert!(registry.take_unique::<String>("unique2").is_ok());
177 }
178
179 #[test]
180 fn test_failed_take_after_cloning() {
181 let mut registry = Registry::new();
182
183 registry.insert_unique("unique3", "Another".to_string());
184 assert_eq!(
185 registry.clone_unique::<String>("unique3").unwrap(),
186 "Another"
187 );
188
189 assert_eq!(
191 registry.take_unique::<String>("unique3").unwrap(),
192 "Another"
193 );
194
195 assert!(registry.take_unique::<String>("unique3").is_err());
197 }
198}