use crate::{InjectableError, InjectableResult, ResolveContext};
#[async_trait::async_trait]
pub trait Extract: Sized {
async fn extract(ctx: &ResolveContext) -> InjectableResult<Self>;
}
#[async_trait::async_trait]
impl Extract for () {
async fn extract(_ctx: &ResolveContext) -> InjectableResult<Self> {
Ok(())
}
}
macro_rules! impl_extract_tuple {
($($T:ident),+) => {
#[async_trait::async_trait]
impl<$($T: Extract + Send + Sync + 'static),+> Extract for ($($T,)+) {
async fn extract(ctx: &ResolveContext) -> InjectableResult<Self> {
Ok(($($T::extract(ctx).await?,)+))
}
}
};
}
impl_extract_tuple!(T1);
impl_extract_tuple!(T1, T2);
impl_extract_tuple!(T1, T2, T3);
impl_extract_tuple!(T1, T2, T3, T4);
impl_extract_tuple!(T1, T2, T3, T4, T5);
impl_extract_tuple!(T1, T2, T3, T4, T5, T6);
impl_extract_tuple!(T1, T2, T3, T4, T5, T6, T7);
impl_extract_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);
impl_extract_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
impl_extract_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
impl_extract_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
impl_extract_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
impl_extract_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);
impl_extract_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);
impl_extract_tuple!(
T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15
);
impl_extract_tuple!(
T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16
);
#[async_trait::async_trait]
impl<T: Extract + Send + Sync + 'static> Extract for Option<T> {
async fn extract(ctx: &ResolveContext) -> InjectableResult<Self> {
match T::extract(ctx).await {
Ok(value) => Ok(Some(value)),
Err(InjectableError::MissingDependency { .. }) => Ok(None),
Err(e) => Err(e),
}
}
}