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{}