use crate::{Prepare, PrepareError, ServerPrepare};
use futures::future::Ready;
use std::any::type_name;
use std::convert::Infallible;
use std::future::Future;
impl<C, Effect, Log, State, Graceful, Decorator>
ServerPrepare<C, Effect, Log, State, Graceful, Decorator>
{
pub fn set_decorator<D>(self, decorator: D) -> ServerPrepare<C, Effect, Log, State, Graceful, D>
where
D: PrepareDecorator,
{
ServerPrepare::new(
self.prepares.change_decorator(decorator),
self.graceful,
self.state,
self.span,
)
}
pub fn prepare_decorator<D, P>(
self,
prepare: P,
) -> ServerPrepare<C, Effect, Log, State, Graceful, D>
where
P: Prepare<C, Effect = D, Error = Infallible, Future = Ready<Result<D, Infallible>>>,
C: 'static,
D: PrepareDecorator,
{
let decorator = prepare
.prepare(self.prepares.get_configure())
.into_inner()
.unwrap();
self.set_decorator(decorator)
}
}
pub trait PrepareDecorator: 'static {
type OutFut<Fut, T>: Future<Output = Result<T, PrepareError>> + 'static
where
Fut: Future<Output = Result<T, PrepareError>> + 'static,
T: 'static;
fn decorator<Fut, T>(&self, src: &'static str, in_fut: Fut) -> Self::OutFut<Fut, T>
where
Fut: Future<Output = Result<T, PrepareError>> + 'static,
T: 'static;
fn prepare_decorator<C, P, Fut>(&self, in_fut: Fut) -> Self::OutFut<Fut, P::Effect>
where
Fut: Future<Output = Result<P::Effect, PrepareError>> + 'static,
P: Prepare<C>,
C: 'static,
{
PrepareDecorator::decorator(self, type_name::<P>(), in_fut)
}
}
pub struct EmptyDecorator;
impl PrepareDecorator for EmptyDecorator {
type OutFut<Fut, T> = Fut where Fut: Future<Output=Result<T, PrepareError>> + 'static, T: 'static;
fn decorator<Fut, T>(&self, _src: &'static str, in_fut: Fut) -> Self::OutFut<Fut, T>
where
Fut: Future<Output = Result<T, PrepareError>> + 'static,
T: 'static,
{
in_fut
}
}