1use crate::entry::IServiceResolver;
2use crate::error::RdiError;
3use crate::provider::ServiceProvider;
4use std::any::{Any, TypeId};
5use std::sync::Arc;
6
7pub struct ServiceProviderWrapper {
8 child: Arc<ServiceProvider>,
9 root: Arc<ServiceProvider>,
10}
11
12impl ServiceProviderWrapper {
13 pub fn new(child: Arc<ServiceProvider>, root: Arc<ServiceProvider>) -> Arc<Self> {
14 Arc::new(Self { child, root })
15 }
16 pub fn child(&self) -> &Arc<ServiceProvider> {
17 &self.child
18 }
19 pub fn root(&self) -> &Arc<ServiceProvider> {
20 &self.root
21 }
22
23 pub fn get<T: ?Sized + Send + Sync + 'static>(&self) -> Result<Arc<T>, RdiError> {
24 let type_name = std::any::type_name::<T>();
25 self.try_get::<T>()
26 .ok_or(RdiError::ServiceNotFound { ty: type_name, context: None })
27 }
28 pub fn get_optional<T: ?Sized + Send + Sync + 'static>(&self) -> Option<Arc<T>> {
29 self.try_get::<T>()
30 }
31 pub fn get_keyed<T: ?Sized + Send + Sync + 'static>(&self, key: &str) -> Result<Arc<T>, RdiError> {
32 let type_name = std::any::type_name::<T>();
33 self.try_get_keyed::<T>(key).ok_or(RdiError::KeyedServiceNotFound {
34 key: key.to_string(),
35 ty: type_name,
36 })
37 }
38 pub fn get_all<T: ?Sized + Send + Sync + 'static>(&self) -> Vec<Arc<T>> {
39 let mut r = self.child.get_all::<T>();
40 r.extend(self.root.get_all::<T>());
41 r
42 }
43 pub fn get_named<T: Send + Sync + 'static>(&self, name: &str) -> Option<Arc<T>> {
44 self.child
45 .get_named::<T>(name)
46 .or_else(|| self.root.get_named::<T>(name))
47 }
48 pub fn get_named_any(&self, name: &str) -> Option<Arc<dyn Any + Send + Sync>> {
49 self.child
50 .get_named_any(name)
51 .or_else(|| self.root.get_named_any(name))
52 }
53
54 pub fn get_owned<T: Send + Sync + 'static>(&self) -> Result<T, RdiError> {
57 let type_name = std::any::type_name::<T>();
58 self.try_get_owned::<T>()
59 .ok_or(RdiError::ServiceNotFound { ty: type_name, context: None })
60 }
61 pub fn try_get_owned<T: Send + Sync + 'static>(&self) -> Option<T> {
63 let arc_any = IServiceResolver::get_owned_any(self.child.as_ref(), std::any::type_name::<T>())
64 .or_else(|| {
65 IServiceResolver::get_owned_any(self.root.as_ref(), std::any::type_name::<T>())
66 })?;
67 let arc_t = crate::provider::ServiceProvider::extract::<T>(arc_any)?;
68 Arc::try_unwrap(arc_t).ok()
69 }
70 pub fn get_keyed_owned<T: Send + Sync + 'static>(&self, key: &str) -> Result<T, RdiError> {
72 let type_name = std::any::type_name::<T>();
73 self.try_get_keyed_owned::<T>(key).ok_or(RdiError::KeyedServiceNotFound {
74 key: key.to_string(),
75 ty: type_name,
76 })
77 }
78 pub fn try_get_keyed_owned<T: Send + Sync + 'static>(&self, key: &str) -> Option<T> {
80 let arc_any =
81 IServiceResolver::get_keyed_owned_any(self.child.as_ref(), std::any::type_name::<T>(), key)
82 .or_else(|| {
83 IServiceResolver::get_keyed_owned_any(self.root.as_ref(), std::any::type_name::<T>(), key)
84 })?;
85 let arc_t = crate::provider::ServiceProvider::extract::<T>(arc_any)?;
86 Arc::try_unwrap(arc_t).ok()
87 }
88
89 pub async fn get_async<T: ?Sized + Send + Sync + 'static>(&self) -> Result<Arc<T>, RdiError> {
91 match self.child.get_async::<T>().await {
92 Ok(svc) => Ok(svc),
93 Err(_) => self.root.get_async::<T>().await,
94 }
95 }
96 pub async fn get_keyed_async<T: ?Sized + Send + Sync + 'static>(
98 &self,
99 key: &str,
100 ) -> Result<Arc<T>, RdiError> {
101 match self.child.get_keyed_async::<T>(key).await {
102 Ok(svc) => Ok(svc),
103 Err(_) => self.root.get_keyed_async::<T>(key).await,
104 }
105 }
106
107 fn try_get<T: ?Sized + Send + Sync + 'static>(&self) -> Option<Arc<T>> {
108 self.child
109 .get_optional::<T>()
110 .or_else(|| self.root.get_optional::<T>())
111 }
112
113 fn try_get_keyed<T: ?Sized + Send + Sync + 'static>(&self, key: &str) -> Option<Arc<T>> {
114 IServiceResolver::get_keyed_any(self.child.as_ref(), std::any::type_name::<T>(), key)
116 .or_else(|| {
117 IServiceResolver::get_keyed_any(self.root.as_ref(), std::any::type_name::<T>(), key)
118 })
119 .and_then(|arc| crate::provider::ServiceProvider::extract(arc))
120 }
121}
122
123impl IServiceResolver for ServiceProviderWrapper {
124 fn get_any(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>> {
125 IServiceResolver::get_any(self.child.as_ref(), key)
126 .or_else(|| IServiceResolver::get_any(self.root.as_ref(), key))
127 }
128 fn get_keyed_any(&self, key: &str, variant: &str) -> Option<Arc<dyn Any + Send + Sync>> {
129 IServiceResolver::get_keyed_any(self.child.as_ref(), key, variant)
130 .or_else(|| IServiceResolver::get_keyed_any(self.root.as_ref(), key, variant))
131 }
132 fn get_by_type_id(&self, tid: TypeId) -> Option<Arc<dyn Any + Send + Sync>> {
133 self.child
134 .get_by_type_id(tid)
135 .or_else(|| self.root.get_by_type_id(tid))
136 }
137 fn get_keyed_by_type_id(
138 &self,
139 tid: TypeId,
140 key: &str,
141 ) -> Option<Arc<dyn Any + Send + Sync>> {
142 self.child
143 .get_keyed_by_type_id(tid, key)
144 .or_else(|| self.root.get_keyed_by_type_id(tid, key))
145 }
146 fn get_all_any(&self, key: &str) -> Vec<Arc<dyn Any + Send + Sync>> {
147 let mut result = IServiceResolver::get_all_any(self.child.as_ref(), key);
149 result.extend(IServiceResolver::get_all_any(self.root.as_ref(), key));
150 result
151 }
152 fn get_owned_any(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>> {
153 IServiceResolver::get_owned_any(self.child.as_ref(), key)
154 .or_else(|| IServiceResolver::get_owned_any(self.root.as_ref(), key))
155 }
156 fn get_keyed_owned_any(
157 &self,
158 key: &str,
159 variant: &str,
160 ) -> Option<Arc<dyn Any + Send + Sync>> {
161 IServiceResolver::get_keyed_owned_any(self.child.as_ref(), key, variant)
162 .or_else(|| IServiceResolver::get_keyed_owned_any(self.root.as_ref(), key, variant))
163 }
164 fn provider_arc(&self) -> Option<Arc<ServiceProvider>> {
165 Some(Arc::clone(&self.child))
166 }
167}
168
169impl ServiceProviderWrapper {
170 pub fn rdi_register_named(&self, name: &str, service: Arc<dyn Any + Send + Sync>) {
172 self.child.rdi_register_named(name, service);
173 }
174
175 pub fn rdi_remove_named(&self, name: &str) {
177 self.child.rdi_remove_named(name);
178 }
179}
180
181#[cfg(test)]
182mod tests {
183 use super::*;
184 use crate::collection::ServiceCollection;
185 #[derive(Debug, PartialEq)]
186 struct PO;
187 #[derive(Debug, PartialEq)]
188 struct RO {
189 v: i32,
190 }
191 #[derive(Debug, PartialEq)]
192 struct B {
193 s: String,
194 }
195 #[test]
196 fn child_prio() {
197 let r = ServiceCollection::new()
198 .singleton(|_| Arc::new(B { s: "root".into() }))
199 .build()
200 .unwrap();
201 let c = ServiceCollection::new()
202 .singleton(|_| Arc::new(B { s: "child".into() }))
203 .build()
204 .unwrap();
205 let w = ServiceProviderWrapper::new(c, r);
206 assert_eq!(w.get::<B>().unwrap().s, "child");
207 }
208 #[test]
209 fn root_fallback() {
210 let r = ServiceCollection::new()
211 .singleton(|_| Arc::new(RO { v: 42 }))
212 .build()
213 .unwrap();
214 let c = ServiceCollection::new().build().unwrap();
215 let w = ServiceProviderWrapper::new(c, r);
216 assert_eq!(w.get::<RO>().unwrap().v, 42);
217 }
218 #[test]
219 fn child_invisible() {
220 let r = ServiceCollection::new().build().unwrap();
221 let c = ServiceCollection::new()
222 .singleton(|_| Arc::new(PO))
223 .build()
224 .unwrap();
225 let _w = ServiceProviderWrapper::new(c, r.clone());
226 assert!(r.get_optional::<PO>().is_none());
227 }
228}