1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use crate::{
InjectResult, Injector, RequestInfo, Service, ServiceFactory, Svc,
TypedProvider,
};
use std::marker::PhantomData;
pub struct SingletonProvider<D, R, F>
where
R: Service,
F: ServiceFactory<D, Result = R>,
{
factory: F,
result: Option<Svc<R>>,
marker: PhantomData<fn(D) -> R>,
}
impl<D, R, F> SingletonProvider<D, R, F>
where
R: Service,
F: ServiceFactory<D, Result = R>,
{
#[must_use]
pub fn new(func: F) -> Self {
SingletonProvider {
factory: func,
result: None,
marker: PhantomData,
}
}
}
impl<D, R, F> TypedProvider for SingletonProvider<D, R, F>
where
D: Service,
R: Service,
F: ServiceFactory<D, Result = R>,
{
type Result = R;
fn provide_typed(
&mut self,
injector: &Injector,
request_info: &RequestInfo,
) -> InjectResult<Svc<Self::Result>> {
if let Some(ref service) = self.result {
return Ok(service.clone());
}
let result = self.factory.invoke(injector, request_info)?;
let result = Svc::new(result);
self.result = Some(result.clone());
Ok(result)
}
}
pub trait IntoSingleton<D, R, F>
where
R: Service,
F: ServiceFactory<D, Result = R>,
{
#[must_use]
fn singleton(self) -> SingletonProvider<D, R, F>;
}
impl<D, R, F> IntoSingleton<D, R, F> for F
where
R: Service,
F: ServiceFactory<D, Result = R>,
{
fn singleton(self) -> SingletonProvider<D, R, F> {
SingletonProvider::new(self)
}
}
impl<D, R, F> From<F> for SingletonProvider<D, R, F>
where
R: Service,
F: ServiceFactory<D, Result = R>,
{
fn from(func: F) -> Self {
func.singleton()
}
}