1#![allow(clippy::missing_errors_doc, clippy::manual_async_fn)]
4
5use std::any::TypeId;
6
7use crate::error::ResolveError;
8use crate::types::Registerable;
9use crate::Registry;
10
11pub(crate) mod private {
13 #[allow(missing_debug_implementations)]
16 #[derive(Clone, Copy)]
17 pub struct SealToken;
18}
19
20pub trait DepBuilder<R> {
30 #[cfg(not(feature = "tokio"))]
43 fn build(
44 registry: &Registry,
45 ctor: &dyn crate::types::TransientCtorFallibleDeps<R, Self>,
46 _: private::SealToken,
47 ) -> Result<R, ResolveError>
48 where
49 R: Sized;
50
51 #[cfg(not(feature = "tokio"))]
58 fn build_once(
59 registry: &Registry,
60 ctor: Box<dyn crate::types::SingletonCtorFallibleDeps<R, Self>>,
61 _: private::SealToken,
62 ) -> Result<R, ResolveError>
63 where
64 R: Sized,
65 Self: Sized;
66
67 #[cfg(feature = "tokio")]
80 fn build(
81 registry: &Registry,
82 ctor: &(dyn crate::types::TransientCtorFallibleDeps<R, Self> + Send),
83 _: private::SealToken,
84 ) -> impl std::future::Future<Output = Result<R, ResolveError>> + Send + Sync
85 where
86 R: Sized;
87
88 #[cfg(feature = "tokio")]
95 fn build_once(
96 registry: &Registry,
97 ctor: Box<dyn crate::types::SingletonCtorFallibleDeps<R, Self> + Send>,
98 _: private::SealToken,
99 ) -> impl std::future::Future<Output = Result<R, ResolveError>> + Send + Sync
100 where
101 R: Sized,
102 Self: Sized;
103
104 fn as_typeids(_: private::SealToken) -> Vec<(TypeId, &'static str)>;
111}
112
113impl<R> DepBuilder<R> for ()
114where
115 R: Registerable,
116{
117 #[cfg(not(feature = "tokio"))]
118 fn build(
119 _registry: &Registry,
120 ctor: &dyn crate::types::TransientCtorFallibleDeps<R, Self>,
121 _: private::SealToken,
122 ) -> Result<R, ResolveError> {
123 (ctor)(()).map_err(ResolveError::Ctor)
124 }
125
126 #[cfg(not(feature = "tokio"))]
127 fn build_once(
128 _registry: &Registry,
129 ctor: Box<dyn crate::types::SingletonCtorFallibleDeps<R, Self>>,
130 _: private::SealToken,
131 ) -> Result<R, ResolveError>
132 where
133 R: Sized,
134 Self: Sized,
135 {
136 ctor(()).map_err(ResolveError::Ctor)
137 }
138
139 #[cfg(feature = "tokio")]
140 fn build(
141 _registry: &Registry,
142 ctor: &(dyn crate::types::TransientCtorFallibleDeps<R, Self> + Send),
143 _: private::SealToken,
144 ) -> impl std::future::Future<Output = Result<R, ResolveError>> + Send + Sync
145 {
146 async move {
147 (ctor)(()).await.map_err(ResolveError::Ctor)
148 }
149 }
150
151 #[cfg(feature = "tokio")]
152 fn build_once(
153 _registry: &Registry,
154 ctor: Box<dyn crate::types::SingletonCtorFallibleDeps<R, Self> + Send>,
155 _: private::SealToken,
156 ) -> impl std::future::Future<Output = Result<R, ResolveError>> + Send + Sync
157 where
158 R: Sized,
159 Self: Sized,
160 {
161 async move {
162 (ctor)(()).await.map_err(ResolveError::Ctor)
163 }
164 }
165
166 fn as_typeids(_: private::SealToken) -> Vec<(TypeId, &'static str)> {
167 Vec::new()
168 }
169}
170
171macro_rules! DepBuilderImpl {
173 ($n:expr, { $($ts:ident),+ }) => {
174 impl<R, $($ts,)*> $crate::dependency_builder::DepBuilder<R> for ($($ts,)*)
175 where
176 R: $crate::types::Registerable,
177 $($ts: $crate::dependencies::Dep,)*
178 {
179 #[cfg(not(feature = "tokio"))]
180 fn build(
181 registry: &$crate::registry::Registry,
182 ctor: &dyn crate::types::TransientCtorFallibleDeps<R, Self>,
183 _: private::SealToken,
184 ) -> Result<R, ResolveError>
185 {
186 registry.validate::<R>()?;
187
188 let deps = (
189 $(
190 <$ts>::new(registry),
191 )*
192 );
193
194 (ctor)(deps).map_err(ResolveError::Ctor)
195 }
196
197 #[cfg(not(feature = "tokio"))]
198 fn build_once(
199 registry: &$crate::registry::Registry,
200 ctor: Box<dyn crate::types::SingletonCtorFallibleDeps<R, Self>>,
201 _: private::SealToken,
202 ) -> Result<R, ResolveError>
203 where
204 R: Sized,
205 Self: Sized
206 {
207 registry.validate::<R>()?;
208
209 let deps = (
210 $(
211 <$ts>::new(registry),
212 )*
213 );
214
215 ctor(deps).map_err(ResolveError::Ctor)
216 }
217
218 #[cfg(feature = "tokio")]
219 fn build(
220 registry: &Registry,
221 ctor: &(dyn crate::types::TransientCtorFallibleDeps<R, Self> + Send),
222 _: private::SealToken,
223 ) -> impl std::future::Future<Output = Result<R, ResolveError>> + Send + Sync
224 {
225 async move {
226 registry.validate::<R>()?;
227
228 let deps = (
229 $(
230 <$ts>::new(registry).await,
231 )*
232 );
233
234 (ctor)(deps).await.map_err(ResolveError::Ctor)
235 }
236 }
237
238 #[cfg(feature = "tokio")]
239 fn build_once(
240 registry: &Registry,
241 ctor: Box<dyn crate::types::SingletonCtorFallibleDeps<R, Self> + Send>,
242 _: private::SealToken,
243 ) -> impl std::future::Future<Output = Result<R, ResolveError>> + Send + Sync
244 {
245 async move {
246 registry.validate::<R>()?;
247
248 let deps = (
249 $(
250 <$ts>::new(registry).await,
251 )*
252 );
253
254 (ctor)(deps).await.map_err(ResolveError::Ctor)
255 }
256 }
257
258 fn as_typeids(_: private::SealToken) -> ::std::vec::Vec<(::std::any::TypeId, &'static str)> {
259 ::std::vec![ $((<$ts>::type_id(), ::std::any::type_name::<$ts>()),)* ]
260 }
261 }
262 };
263}
264
265DepBuilderImpl!(1, { T1 });
266DepBuilderImpl!(2, { T1, T2 });
267DepBuilderImpl!(3, { T1, T2, T3 });
268DepBuilderImpl!(4, { T1, T2, T3, T4 });
269DepBuilderImpl!(5, { T1, T2, T3, T4, T5 });
270DepBuilderImpl!(6, { T1, T2, T3, T4, T5, T6 });
271DepBuilderImpl!(7, { T1, T2, T3, T4, T5, T6, T8 });
272DepBuilderImpl!(8, { T1, T2, T3, T4, T5, T6, T8, T9 });