Skip to main content

auto_di/
deferred.rs

1use std::{any::Any, marker::PhantomData, sync::Arc};
2
3use crate::{DiError, resolve};
4
5/// Resolves a dependency each time [`Provider::get`] is called.
6pub struct Provider<T> {
7    _marker: PhantomData<fn() -> T>,
8}
9
10impl<T> Clone for Provider<T> {
11    fn clone(&self) -> Self {
12        Self::default()
13    }
14}
15
16impl<T> Default for Provider<T> {
17    fn default() -> Self {
18        Self {
19            _marker: PhantomData,
20        }
21    }
22}
23
24impl<T> Provider<T>
25where
26    T: Any + Send + Sync,
27{
28    pub async fn get(&self) -> Result<Arc<T>, DiError> {
29        resolve::<T>().await
30    }
31}
32
33/// Resolves a dependency on first access and caches it locally.
34pub struct Lazy<T> {
35    cell: tokio::sync::OnceCell<Arc<T>>,
36}
37
38impl<T> Default for Lazy<T> {
39    fn default() -> Self {
40        Self {
41            cell: tokio::sync::OnceCell::new(),
42        }
43    }
44}
45
46impl<T> Lazy<T>
47where
48    T: Any + Send + Sync,
49{
50    pub async fn get(&self) -> Result<&Arc<T>, DiError> {
51        self.cell
52            .get_or_try_init(|| async { resolve::<T>().await })
53            .await
54    }
55}