Skip to main content

a3s_boot/provider/
definition.rs

1use super::{AnyProvider, ModuleRef, ProviderToken};
2use crate::Result;
3use std::fmt;
4use std::sync::Arc;
5
6type ProviderFactory = dyn Fn(&ModuleRef) -> Result<Arc<AnyProvider>> + Send + Sync;
7
8/// A provider registration, similar to a Nest provider entry.
9#[derive(Clone)]
10pub struct ProviderDefinition {
11    token: ProviderToken,
12    factory: Arc<ProviderFactory>,
13}
14
15impl fmt::Debug for ProviderDefinition {
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        f.debug_struct("ProviderDefinition")
18            .field("token", &self.token)
19            .finish_non_exhaustive()
20    }
21}
22
23impl ProviderDefinition {
24    pub fn singleton<T>(value: T) -> Self
25    where
26        T: Send + Sync + 'static,
27    {
28        Self::from_arc(Arc::new(value))
29    }
30
31    pub fn named_singleton<T>(token: impl Into<String>, value: T) -> Self
32    where
33        T: Send + Sync + 'static,
34    {
35        Self::named_from_arc(token, Arc::new(value))
36    }
37
38    pub fn from_arc<T>(value: Arc<T>) -> Self
39    where
40        T: Send + Sync + 'static,
41    {
42        let token = ProviderToken::of::<T>();
43        Self::named_from_arc(token.as_str(), value)
44    }
45
46    pub fn named_from_arc<T>(token: impl Into<String>, value: Arc<T>) -> Self
47    where
48        T: Send + Sync + 'static,
49    {
50        let token = ProviderToken::named(token);
51        let factory_value = Arc::clone(&value);
52        Self {
53            token,
54            factory: Arc::new(move |_| Ok(Arc::clone(&factory_value) as Arc<AnyProvider>)),
55        }
56    }
57
58    pub fn factory<T, F>(factory: F) -> Self
59    where
60        T: Send + Sync + 'static,
61        F: Fn(&ModuleRef) -> Result<T> + Send + Sync + 'static,
62    {
63        Self::named_factory(ProviderToken::of::<T>().as_str(), factory)
64    }
65
66    pub fn factory_arc<T, F>(factory: F) -> Self
67    where
68        T: Send + Sync + 'static,
69        F: Fn(&ModuleRef) -> Result<Arc<T>> + Send + Sync + 'static,
70    {
71        Self::named_factory_arc(ProviderToken::of::<T>().as_str(), factory)
72    }
73
74    pub fn named_factory<T, F>(token: impl Into<String>, factory: F) -> Self
75    where
76        T: Send + Sync + 'static,
77        F: Fn(&ModuleRef) -> Result<T> + Send + Sync + 'static,
78    {
79        Self {
80            token: ProviderToken::named(token),
81            factory: Arc::new(move |module_ref| {
82                Ok(Arc::new(factory(module_ref)?) as Arc<AnyProvider>)
83            }),
84        }
85    }
86
87    pub fn named_factory_arc<T, F>(token: impl Into<String>, factory: F) -> Self
88    where
89        T: Send + Sync + 'static,
90        F: Fn(&ModuleRef) -> Result<Arc<T>> + Send + Sync + 'static,
91    {
92        Self {
93            token: ProviderToken::named(token),
94            factory: Arc::new(move |module_ref| Ok(factory(module_ref)? as Arc<AnyProvider>)),
95        }
96    }
97
98    pub fn token(&self) -> &ProviderToken {
99        &self.token
100    }
101
102    pub(super) fn build(&self, module_ref: &ModuleRef) -> Result<Arc<AnyProvider>> {
103        (self.factory)(module_ref)
104    }
105}