use super::Layer; use std::fmt; /// Returns a new [`LayerFn`] that implements [`Layer`] by calling the /// given function. /// /// The [`Layer::layer`] method takes a type implementing [`Service`] and /// returns a different type implementing [`Service`]. In many cases, this can /// be implemented by a function or a closure. The [`LayerFn`] helper allows /// writing simple [`Layer`] implementations without needing the boilerplate of /// a new struct implementing [`Layer`]. /// /// # Example /// ```rust /// # use tower::Service; /// # use std::task::{Poll, Context}; /// # use tower_layer::{Layer, layer_fn}; /// # use std::fmt; /// # use std::convert::Infallible; /// # /// // A middleware that logs requests before forwarding them to another service /// pub struct LogService { /// target: &'static str, /// service: S, /// } /// /// impl Service for LogService /// where /// S: Service, /// Request: fmt::Debug, /// { /// type Response = S::Response; /// type Error = S::Error; /// type Future = S::Future; /// /// fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { /// self.service.poll_ready(cx) /// } /// /// fn call(&mut self, request: Request) -> Self::Future { /// // Log the request /// println!("request = {:?}, target = {:?}", request, self.target); /// /// self.service.call(request) /// } /// } /// /// // A `Layer` that wraps services in `LogService` /// let log_layer = layer_fn(|service| { /// LogService { /// service, /// target: "tower-docs", /// } /// }); /// /// // An example service. This one uppercases strings /// let uppercase_service = tower::service_fn(|request: String| async move { /// Ok::<_, Infallible>(request.to_uppercase()) /// }); /// /// // Wrap our service in a `LogService` so requests are logged. /// let wrapped_service = log_layer.layer(uppercase_service); /// ``` /// /// [`Service`]: https://docs.rs/tower-service/latest/tower_service/trait.Service.html /// [`Layer::layer`]: crate::Layer::layer pub fn layer_fn(f: T) -> LayerFn { LayerFn { f } } /// A `Layer` implemented by a closure. See the docs for [`layer_fn`] for more details. #[derive(Clone, Copy)] pub struct LayerFn { f: F, } impl Layer for LayerFn where F: Fn(S) -> Out, { type Service = Out; fn layer(&self, inner: S) -> Self::Service { (self.f)(inner) } } impl fmt::Debug for LayerFn { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("LayerFn") .field("f", &format_args!("{}", std::any::type_name::())) .finish() } } #[cfg(test)] mod tests { use super::*; #[allow(dead_code)] #[test] fn layer_fn_has_useful_debug_impl() { struct WrappedService { inner: S, } let layer = layer_fn(|svc| WrappedService { inner: svc }); let _svc = layer.layer("foo"); assert_eq!( "LayerFn { f: tower_layer::layer_fn::tests::layer_fn_has_useful_debug_impl::{{closure}} }".to_string(), format!("{:?}", layer), ); } }