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
use crate::{
InjectError, InjectResult, Injector, RequestInfo, Service, ServiceInfo,
Svc, TypedProvider,
};
pub struct ConditionalProvider<P, F>
where
P: TypedProvider,
F: Service + Fn(&Injector, &RequestInfo) -> bool,
{
inner: P,
condition: F,
}
impl<P, F> TypedProvider for ConditionalProvider<P, F>
where
P: TypedProvider,
F: Service + Fn(&Injector, &RequestInfo) -> bool,
{
type Result = P::Result;
#[inline]
fn provide_typed(
&mut self,
injector: &Injector,
request_info: &RequestInfo,
) -> InjectResult<Svc<Self::Result>> {
if (self.condition)(injector, request_info) {
self.inner.provide_typed(injector, request_info)
} else {
Err(InjectError::ConditionsNotMet {
service_info: ServiceInfo::of::<Self::Result>(),
})
}
}
#[inline]
fn provide_owned_typed(
&mut self,
injector: &Injector,
request_info: &RequestInfo,
) -> InjectResult<Box<Self::Result>> {
if (self.condition)(injector, request_info) {
self.inner.provide_owned_typed(injector, request_info)
} else {
Err(InjectError::ConditionsNotMet {
service_info: ServiceInfo::of::<Self::Result>(),
})
}
}
}
pub trait WithCondition: TypedProvider {
#[must_use]
fn with_condition<F>(self, condition: F) -> ConditionalProvider<Self, F>
where
F: Service + Fn(&Injector, &RequestInfo) -> bool;
}
impl<P> WithCondition for P
where
P: TypedProvider,
{
#[inline]
fn with_condition<F>(self, condition: F) -> ConditionalProvider<Self, F>
where
F: Service + Fn(&Injector, &RequestInfo) -> bool,
{
ConditionalProvider {
condition,
inner: self,
}
}
}