a3s_boot/provider/
definition.rs1use 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#[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}