Skip to main content

camel_core/shared/components/domain/
registry.rs

1use std::collections::HashMap;
2use std::sync::Arc;
3
4use camel_api::CamelError;
5use camel_component_api::Component;
6
7/// Registry that stores components by their URI scheme.
8pub struct Registry {
9    components: HashMap<String, Arc<dyn Component>>,
10}
11
12impl Registry {
13    /// Create an empty registry.
14    pub fn new() -> Self {
15        Self {
16            components: HashMap::new(),
17        }
18    }
19
20    /// Register a component. Replaces any existing component with the same scheme.
21    pub fn register(&mut self, component: Arc<dyn Component>) {
22        self.components
23            .insert(component.scheme().to_string(), component);
24    }
25
26    /// Look up a component by scheme.
27    pub fn get(&self, scheme: &str) -> Option<Arc<dyn Component>> {
28        self.components.get(scheme).cloned()
29    }
30
31    /// Look up a component by scheme, returning an error if not found.
32    pub fn get_or_err(&self, scheme: &str) -> Result<Arc<dyn Component>, CamelError> {
33        self.get(scheme)
34            .ok_or_else(|| CamelError::ComponentNotFound(scheme.to_string()))
35    }
36
37    /// Returns the number of registered components.
38    pub fn len(&self) -> usize {
39        self.components.len()
40    }
41
42    /// Returns true if no components are registered.
43    pub fn is_empty(&self) -> bool {
44        self.components.is_empty()
45    }
46}
47
48impl Default for Registry {
49    fn default() -> Self {
50        Self::new()
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57    use camel_component_log::LogComponent;
58    use camel_component_timer::TimerComponent;
59
60    #[test]
61    fn registry_starts_empty() {
62        let registry = Registry::new();
63        assert!(registry.is_empty());
64        assert_eq!(registry.len(), 0);
65        assert!(registry.get("timer").is_none());
66    }
67
68    #[test]
69    fn registry_registers_and_gets_components() {
70        let mut registry = Registry::new();
71        registry.register(Arc::new(TimerComponent::new()));
72        registry.register(Arc::new(LogComponent::new()));
73
74        assert_eq!(registry.len(), 2);
75        assert!(registry.get("timer").is_some());
76        assert!(registry.get("log").is_some());
77        assert!(!registry.is_empty());
78    }
79
80    #[test]
81    fn registry_get_or_err_reports_missing_component() {
82        let mut registry = Registry::new();
83        registry.register(Arc::new(TimerComponent::new()));
84
85        let err = match registry.get_or_err("missing") {
86            Ok(_) => panic!("must fail"),
87            Err(err) => err,
88        };
89        assert!(matches!(err, CamelError::ComponentNotFound(_)));
90    }
91
92    #[test]
93    fn registry_replaces_component_with_same_scheme() {
94        let mut registry = Registry::new();
95        registry.register(Arc::new(TimerComponent::new()));
96        registry.register(Arc::new(TimerComponent::new()));
97
98        assert_eq!(registry.len(), 1);
99        assert!(registry.get("timer").is_some());
100    }
101}