firebase_rs_sdk/component/
container.rs

1use std::collections::HashMap;
2use std::sync::{Arc, Mutex};
3
4use crate::component::provider::Provider;
5use crate::component::types::{ComponentError, DynService};
6use crate::component::Component;
7
8#[derive(Clone)]
9pub struct ComponentContainer {
10    pub(crate) inner: Arc<ComponentContainerInner>,
11}
12
13pub(crate) struct ComponentContainerInner {
14    pub name: Arc<str>,
15    pub providers: Mutex<HashMap<Arc<str>, Provider>>, // Provider holds Arc to inner state
16    pub root_service: Mutex<Option<DynService>>,
17}
18
19impl ComponentContainer {
20    pub fn new(name: impl Into<String>) -> Self {
21        let name: Arc<str> = Arc::from(name.into());
22        Self {
23            inner: Arc::new(ComponentContainerInner {
24                name,
25                providers: Mutex::new(HashMap::new()),
26                root_service: Mutex::new(None),
27            }),
28        }
29    }
30
31    pub fn name(&self) -> &str {
32        &self.inner.name
33    }
34
35    pub fn add_component(&self, component: Component) -> Result<(), ComponentError> {
36        let provider = self.get_provider(component.name());
37        provider.set_component(component)
38    }
39
40    pub fn add_or_overwrite_component(&self, component: Component) {
41        {
42            let mut guard = self.inner.providers.lock().unwrap();
43            if guard.contains_key(component.name()) {
44                guard.remove(component.name());
45            }
46        }
47        let _ = self.add_component(component);
48    }
49
50    pub fn get_provider(&self, name: &str) -> Provider {
51        if let Some(provider) = self.inner.providers.lock().unwrap().get(name) {
52            return provider.clone();
53        }
54
55        let provider = Provider::new(name, self.clone());
56        self.inner
57            .providers
58            .lock()
59            .unwrap()
60            .insert(Arc::from(name.to_owned()), provider.clone());
61        provider
62    }
63
64    pub fn get_providers(&self) -> Vec<Provider> {
65        self.inner
66            .providers
67            .lock()
68            .unwrap()
69            .values()
70            .cloned()
71            .collect()
72    }
73
74    pub fn attach_root_service(&self, service: DynService) {
75        *self.inner.root_service.lock().unwrap() = Some(service);
76    }
77
78    pub fn root_service<T: 'static + Send + Sync>(&self) -> Option<Arc<T>> {
79        self.inner
80            .root_service
81            .lock()
82            .unwrap()
83            .as_ref()
84            .and_then(|svc| Arc::clone(svc).downcast::<T>().ok())
85    }
86}