async_di/
provider.rs

1use std::sync::Arc;
2use async_trait::async_trait;
3use crate::resolver::ResolverRef;
4use crate::error::Error;
5use crate::helpers::BoxAny;
6
7pub type ProvideResult<T> = anyhow::Result<T>;
8
9#[async_trait]
10pub trait Provider: Send + Sync + 'static {
11  type Ref: Resolvable;
12  async fn provide(&self, resolver: &ResolverRef) -> ProvideResult<Self::Ref>;
13}
14
15#[async_trait]
16pub(crate) trait ProviderObject: Send + Sync + 'static {
17  async fn provide(&self, resolver: &ResolverRef) -> Result<BoxAny, Error>;
18}
19
20#[async_trait]
21impl<T> ProviderObject for T
22  where T: Provider
23{
24  async fn provide(&self, resolver: &ResolverRef) -> Result<BoxAny, Error> {
25    Provider::provide(self, resolver).await
26      .map(|v| Box::new(v) as BoxAny)
27      .map_err(|err| {
28        match err.downcast::<Error>() {
29          Ok(err) => err,
30          Err(err) => Error::Service(Arc::new(err))
31        }
32      })
33  }
34}
35
36pub struct StaticProvider<T>(T);
37
38impl<T> StaticProvider<T> {
39  pub fn new(value: T) -> Self {
40    StaticProvider(value)
41  }
42}
43
44#[async_trait]
45impl<T> Provider for StaticProvider<T>
46where T: Resolvable
47{
48  type Ref = T;
49
50  async fn provide(&self, _: &ResolverRef) -> ProvideResult<Self::Ref> {
51    Ok(self.0.clone())
52  }
53}
54
55mod private {
56  pub trait Sealed {}
57
58  impl<T> Sealed for T {}
59}
60
61pub trait Resolvable: private::Sealed + Clone + Send + Sync + 'static {}
62
63impl<T> Resolvable for T
64  where T: Clone + Send + Sync + ?Sized + 'static
65{}