From f5725a85c75b0722177ccd38dab330406d94848f Mon Sep 17 00:00:00 2001 From: Jonathan Giroux Date: Wed, 31 Aug 2022 12:05:21 +0200 Subject: [PATCH] add ConditionOption middleware --- actix-web/src/middleware/condition_option.rs | 60 ++++++++++++++++++++ actix-web/src/middleware/mod.rs | 2 + 2 files changed, 62 insertions(+) create mode 100644 actix-web/src/middleware/condition_option.rs diff --git a/actix-web/src/middleware/condition_option.rs b/actix-web/src/middleware/condition_option.rs new file mode 100644 index 000000000..e0ecfcabb --- /dev/null +++ b/actix-web/src/middleware/condition_option.rs @@ -0,0 +1,60 @@ +//! For middleware documentation, see [`ConditionOption`]. + +use futures_core::future::LocalBoxFuture; +use futures_util::future::FutureExt as _; + +use crate::{ + body::EitherBody, + dev::{Service, ServiceResponse, Transform}, + middleware::condition::ConditionMiddleware, +}; + +/// Middleware for conditionally enabling other middleware in an [`Option`]. +/// +/// Uses [`Condition`](crate::middleware::condition::Condition) under the hood. +/// +/// # Example +/// ``` +/// use actix_web::middleware::{ConditionOption, NormalizePath}; +/// use actix_web::App; +/// +/// let normalize: ConditionOption<_> = Some(NormalizePath::default()).into(); +/// let app = App::new() +/// .wrap(normalize); +/// ``` +pub struct ConditionOption(Option); + +impl From> for ConditionOption { + fn from(value: Option) -> Self { + Self(value) + } +} + +impl Transform for ConditionOption +where + S: Service, Error = Err> + 'static, + T: Transform, Error = Err>, + T::Future: 'static, + T::InitError: 'static, + T::Transform: 'static, +{ + type Response = ServiceResponse>; + type Error = Err; + type Transform = ConditionMiddleware; + type InitError = T::InitError; + type Future = LocalBoxFuture<'static, Result>; + + fn new_transform(&self, service: S) -> Self::Future { + match &self.0 { + Some(transformer) => { + let fut = transformer.new_transform(service); + async move { + let wrapped_svc = fut.await?; + Ok(ConditionMiddleware::Enable(wrapped_svc)) + } + .boxed_local() + } + None => async move { Ok(ConditionMiddleware::Disable(service)) }.boxed_local(), + } + } +} diff --git a/actix-web/src/middleware/mod.rs b/actix-web/src/middleware/mod.rs index 0a61ad6cb..26f9ec7c0 100644 --- a/actix-web/src/middleware/mod.rs +++ b/actix-web/src/middleware/mod.rs @@ -2,6 +2,7 @@ mod compat; mod condition; +mod condition_option; mod default_headers; mod err_handlers; mod logger; @@ -11,6 +12,7 @@ mod normalize; pub use self::compat::Compat; pub use self::condition::Condition; +pub use self::condition_option::ConditionOption; pub use self::default_headers::DefaultHeaders; pub use self::err_handlers::{ErrorHandlerResponse, ErrorHandlers}; pub use self::logger::Logger;