//! Apply a transformation to the request body. //! //! # Example //! //! ``` //! use http_body_util::Full; //! use bytes::Bytes; //! use http::{Request, Response}; //! use std::convert::Infallible; //! use std::{pin::Pin, task::{ready, Context, Poll}}; //! use tower::{ServiceBuilder, service_fn, ServiceExt, Service}; //! use tower_http::map_request_body::MapRequestBodyLayer; //! //! // A wrapper for a `Full` //! struct BodyWrapper { //! inner: Full, //! } //! //! impl BodyWrapper { //! fn new(inner: Full) -> Self { //! Self { inner } //! } //! } //! //! impl http_body::Body for BodyWrapper { //! // ... //! # type Data = Bytes; //! # type Error = tower::BoxError; //! # fn poll_frame( //! # self: Pin<&mut Self>, //! # cx: &mut Context<'_> //! # ) -> Poll, Self::Error>>> { unimplemented!() } //! # fn is_end_stream(&self) -> bool { unimplemented!() } //! # fn size_hint(&self) -> http_body::SizeHint { unimplemented!() } //! } //! //! async fn handle(_: Request) -> Result>, Infallible> { //! // ... //! # Ok(Response::new(Full::default())) //! } //! //! # #[tokio::main] //! # async fn main() -> Result<(), Box> { //! let mut svc = ServiceBuilder::new() //! // Wrap response bodies in `BodyWrapper` //! .layer(MapRequestBodyLayer::new(BodyWrapper::new)) //! .service_fn(handle); //! //! // Call the service //! let request = Request::new(Full::default()); //! //! svc.ready().await?.call(request).await?; //! # Ok(()) //! # } //! ``` use http::{Request, Response}; use std::{ fmt, task::{Context, Poll}, }; use tower_layer::Layer; use tower_service::Service; /// Apply a transformation to the request body. /// /// See the [module docs](crate::map_request_body) for an example. #[derive(Clone)] pub struct MapRequestBodyLayer { f: F, } impl MapRequestBodyLayer { /// Create a new [`MapRequestBodyLayer`]. /// /// `F` is expected to be a function that takes a body and returns another body. pub fn new(f: F) -> Self { Self { f } } } impl Layer for MapRequestBodyLayer where F: Clone, { type Service = MapRequestBody; fn layer(&self, inner: S) -> Self::Service { MapRequestBody::new(inner, self.f.clone()) } } impl fmt::Debug for MapRequestBodyLayer { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("MapRequestBodyLayer") .field("f", &std::any::type_name::()) .finish() } } /// Apply a transformation to the request body. /// /// See the [module docs](crate::map_request_body) for an example. #[derive(Clone)] pub struct MapRequestBody { inner: S, f: F, } impl MapRequestBody { /// Create a new [`MapRequestBody`]. /// /// `F` is expected to be a function that takes a body and returns another body. pub fn new(service: S, f: F) -> Self { Self { inner: service, f } } /// Returns a new [`Layer`] that wraps services with a `MapRequestBodyLayer` middleware. /// /// [`Layer`]: tower_layer::Layer pub fn layer(f: F) -> MapRequestBodyLayer { MapRequestBodyLayer::new(f) } define_inner_service_accessors!(); } impl Service> for MapRequestBody where S: Service, Response = Response>, F: FnMut(ReqBody) -> NewReqBody, { type Response = S::Response; type Error = S::Error; type Future = S::Future; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { self.inner.poll_ready(cx) } fn call(&mut self, req: Request) -> Self::Future { let req = req.map(&mut self.f); self.inner.call(req) } } impl fmt::Debug for MapRequestBody where S: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("MapRequestBody") .field("inner", &self.inner) .field("f", &std::any::type_name::()) .finish() } }