mirror of https://github.com/fafhrd91/actix-web
static condition middleware future
This commit is contained in:
parent
73b89d6f58
commit
015e1c7b4d
|
@ -1,11 +1,13 @@
|
||||||
//! For middleware documentation, see [`Condition`].
|
//! For middleware documentation, see [`Condition`].
|
||||||
|
|
||||||
|
use std::future::Future;
|
||||||
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use actix_service::{Service, Transform};
|
use actix_service::{Service, Transform};
|
||||||
use actix_utils::future::Either;
|
use actix_utils::future::Either;
|
||||||
use futures_core::future::LocalBoxFuture;
|
|
||||||
use futures_util::future::FutureExt as _;
|
use futures_core::ready;
|
||||||
|
|
||||||
/// Middleware for conditionally enabling other middleware.
|
/// Middleware for conditionally enabling other middleware.
|
||||||
///
|
///
|
||||||
|
@ -48,22 +50,42 @@ where
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
type Transform = ConditionMiddleware<T::Transform, S>;
|
type Transform = ConditionMiddleware<T::Transform, S>;
|
||||||
type InitError = T::InitError;
|
type InitError = T::InitError;
|
||||||
type Future = LocalBoxFuture<'static, Result<Self::Transform, Self::InitError>>;
|
type Future = ConditionFut<<T>::Future, S>;
|
||||||
|
|
||||||
fn new_transform(&self, service: S) -> Self::Future {
|
fn new_transform(&self, service: S) -> Self::Future {
|
||||||
if self.enable {
|
if self.enable {
|
||||||
let fut = self.transformer.new_transform(service);
|
let fut = self.transformer.new_transform(service);
|
||||||
async move {
|
ConditionFut::Enable(fut)
|
||||||
let wrapped_svc = fut.await?;
|
|
||||||
Ok(ConditionMiddleware::Enable(wrapped_svc))
|
|
||||||
}
|
|
||||||
.boxed_local()
|
|
||||||
} else {
|
} else {
|
||||||
async move { Ok(ConditionMiddleware::Disable(service)) }.boxed_local()
|
ConditionFut::Disable(Some(service))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pin_project::pin_project(project = ConditionFutProj)]
|
||||||
|
pub enum ConditionFut<F, D> {
|
||||||
|
Enable(#[pin] F),
|
||||||
|
Disable(Option<D>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, E, D, Ie> Future for ConditionFut<F, D>
|
||||||
|
where
|
||||||
|
F: Future<Output = Result<E, Ie>>,
|
||||||
|
{
|
||||||
|
type Output = Result<ConditionMiddleware<E, D>, Ie>;
|
||||||
|
|
||||||
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
let middleware = match self.project() {
|
||||||
|
ConditionFutProj::Enable(fut) => ConditionMiddleware::Enable(ready!(fut.poll(cx))?),
|
||||||
|
ConditionFutProj::Disable(service) => {
|
||||||
|
ConditionMiddleware::Disable(service.take().unwrap())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Poll::Ready(Ok(middleware))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum ConditionMiddleware<E, D> {
|
pub enum ConditionMiddleware<E, D> {
|
||||||
Enable(E),
|
Enable(E),
|
||||||
Disable(D),
|
Disable(D),
|
||||||
|
|
Loading…
Reference in New Issue