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