tower-layer-0.3.2/.cargo_vcs_info.json0000644000000001510000000000100133050ustar { "git": { "sha1": "8b84b98d93a2493422a0ecddb6251f292a904cff" }, "path_in_vcs": "tower-layer" }tower-layer-0.3.2/CHANGELOG.md000064400000000000000000000016311046102023000137120ustar 00000000000000# 0.3.2 (October 7, 2022) - Implement `Layer` for tuples of up to 16 elements ([#694]) [#694]: https://github.com/tower-rs/tower/pull/694 # 0.3.1 (January 7, 2021) - Added `layer_fn`, for constructing a `Layer` from a function taking a `Service` and returning a different `Service` ([#491]) - Added an implementation of `Layer` for `&Layer` ([#446]) - Multiple documentation improvements ([#487], [#490]) [#491]: https://github.com/tower-rs/tower/pull/491 [#446]: https://github.com/tower-rs/tower/pull/446 [#487]: https://github.com/tower-rs/tower/pull/487 [#490]: https://github.com/tower-rs/tower/pull/490 # 0.3.0 (November 29, 2019) - Move layer builder from `tower-util` to tower-layer. # 0.3.0-alpha.2 (September 30, 2019) - Move to `futures-*-preview 0.3.0-alpha.19` - Move to `pin-project 0.4` # 0.3.0-alpha.1 (September 11, 2019) - Move to `std::future` # 0.1.0 (April 26, 2019) - Initial release tower-layer-0.3.2/Cargo.toml0000644000000017260000000000100113140ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "tower-layer" version = "0.3.2" authors = ["Tower Maintainers "] description = """ Decorates a `Service` to allow easy composition between `Service`s. """ homepage = "https://github.com/tower-rs/tower" readme = "README.md" categories = [ "asynchronous", "network-programming", ] license = "MIT" repository = "https://github.com/tower-rs/tower" [dependencies] [dev-dependencies.tower] version = "0.4" [dev-dependencies.tower-service] version = "0.3.0" tower-layer-0.3.2/Cargo.toml.orig000064400000000000000000000012471046102023000147730ustar 00000000000000[package] name = "tower-layer" # When releasing to crates.io: # - Update doc url # - Cargo.toml # - README.md # - Update CHANGELOG.md. # - Create "v0.1.x" git tag. version = "0.3.2" authors = ["Tower Maintainers "] license = "MIT" readme = "README.md" repository = "https://github.com/tower-rs/tower" homepage = "https://github.com/tower-rs/tower" description = """ Decorates a `Service` to allow easy composition between `Service`s. """ categories = ["asynchronous", "network-programming"] edition = "2018" [dependencies] [dev-dependencies] tower-service = { version = "0.3.0", path = "../tower-service" } tower = { version = "0.4", path = "../tower" } tower-layer-0.3.2/LICENSE000064400000000000000000000020461046102023000131070ustar 00000000000000Copyright (c) 2019 Tower Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. tower-layer-0.3.2/README.md000064400000000000000000000033711046102023000133630ustar 00000000000000# Tower Layer Decorates a [Tower] `Service`, transforming either the request or the response. [![Crates.io][crates-badge]][crates-url] [![Documentation][docs-badge]][docs-url] [![Documentation (master)][docs-master-badge]][docs-master-url] [![MIT licensed][mit-badge]][mit-url] [![Build Status][actions-badge]][actions-url] [![Discord chat][discord-badge]][discord-url] [crates-badge]: https://img.shields.io/crates/v/tower-layer.svg [crates-url]: https://crates.io/crates/tower-layer [docs-badge]: https://docs.rs/tower-layer/badge.svg [docs-url]: https://docs.rs/tower-layer [docs-master-badge]: https://img.shields.io/badge/docs-master-blue [docs-master-url]: https://tower-rs.github.io/tower/tower_layer [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg [mit-url]: LICENSE [actions-badge]: https://github.com/tower-rs/tower/workflows/CI/badge.svg [actions-url]:https://github.com/tower-rs/tower/actions?query=workflow%3ACI [discord-badge]: https://img.shields.io/discord/500028886025895936?logo=discord&label=discord&logoColor=white [discord-url]: https://discord.gg/EeF3cQw ## Overview Often, many of the pieces needed for writing network applications can be reused across multiple services. The `Layer` trait can be used to write reusable components that can be applied to very different kinds of services; for example, it can be applied to services operating on different protocols, and to both the client and server side of a network transaction. ## License This project is licensed under the [MIT license](LICENSE). ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Tower by you, shall be licensed as MIT, without any additional terms or conditions. [Tower]: https://crates.io/crates/towertower-layer-0.3.2/src/identity.rs000064400000000000000000000015741046102023000150750ustar 00000000000000use super::Layer; use std::fmt; /// A no-op middleware. /// /// When wrapping a [`Service`], the [`Identity`] layer returns the provided /// service without modifying it. /// /// [`Service`]: https://docs.rs/tower-service/latest/tower_service/trait.Service.html #[derive(Default, Clone)] pub struct Identity { _p: (), } impl Identity { /// Create a new [`Identity`] value pub fn new() -> Identity { Identity { _p: () } } } /// Decorates a [`Service`], transforming either the request or the response. /// /// [`Service`]: https://docs.rs/tower-service/latest/tower_service/trait.Service.html impl Layer for Identity { type Service = S; fn layer(&self, inner: S) -> Self::Service { inner } } impl fmt::Debug for Identity { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Identity").finish() } } tower-layer-0.3.2/src/layer_fn.rs000064400000000000000000000062351046102023000150420ustar 00000000000000use 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), ); } } tower-layer-0.3.2/src/lib.rs000064400000000000000000000061521046102023000140070ustar 00000000000000#![warn( missing_debug_implementations, missing_docs, rust_2018_idioms, unreachable_pub )] #![forbid(unsafe_code)] // `rustdoc::broken_intra_doc_links` is checked on CI //! Layer traits and extensions. //! //! A layer decorates an service and provides additional functionality. It //! allows other services to be composed with the service that implements layer. //! //! A middleware implements the [`Layer`] and [`Service`] trait. //! //! [`Service`]: https://docs.rs/tower/latest/tower/trait.Service.html mod identity; mod layer_fn; mod stack; mod tuple; pub use self::{ identity::Identity, layer_fn::{layer_fn, LayerFn}, stack::Stack, }; /// Decorates a [`Service`], transforming either the request or the response. /// /// Often, many of the pieces needed for writing network applications can be /// reused across multiple services. The `Layer` trait can be used to write /// reusable components that can be applied to very different kinds of services; /// for example, it can be applied to services operating on different protocols, /// and to both the client and server side of a network transaction. /// /// # Log /// /// Take request logging as an example: /// /// ```rust /// # use tower_service::Service; /// # use std::task::{Poll, Context}; /// # use tower_layer::Layer; /// # use std::fmt; /// /// pub struct LogLayer { /// target: &'static str, /// } /// /// impl Layer for LogLayer { /// type Service = LogService; /// /// fn layer(&self, service: S) -> Self::Service { /// LogService { /// target: self.target, /// service /// } /// } /// } /// /// // This service implements the Log behavior /// 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 { /// // Insert log statement here or other functionality /// println!("request = {:?}, target = {:?}", request, self.target); /// self.service.call(request) /// } /// } /// ``` /// /// The above log implementation is decoupled from the underlying protocol and /// is also decoupled from client or server concerns. In other words, the same /// log middleware could be used in either a client or a server. /// /// [`Service`]: https://docs.rs/tower/latest/tower/trait.Service.html pub trait Layer { /// The wrapped service type Service; /// Wrap the given service with the middleware, returning a new service /// that has been decorated with the middleware. fn layer(&self, inner: S) -> Self::Service; } impl<'a, T, S> Layer for &'a T where T: ?Sized + Layer, { type Service = T::Service; fn layer(&self, inner: S) -> Self::Service { (**self).layer(inner) } } tower-layer-0.3.2/src/stack.rs000064400000000000000000000035651046102023000143530ustar 00000000000000use super::Layer; use std::fmt; /// Two middlewares chained together. #[derive(Clone)] pub struct Stack { inner: Inner, outer: Outer, } impl Stack { /// Create a new `Stack`. pub fn new(inner: Inner, outer: Outer) -> Self { Stack { inner, outer } } } impl Layer for Stack where Inner: Layer, Outer: Layer, { type Service = Outer::Service; fn layer(&self, service: S) -> Self::Service { let inner = self.inner.layer(service); self.outer.layer(inner) } } impl fmt::Debug for Stack where Inner: fmt::Debug, Outer: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // The generated output of nested `Stack`s is very noisy and makes // it harder to understand what is in a `ServiceBuilder`. // // Instead, this output is designed assuming that a `Stack` is // usually quite nested, and inside a `ServiceBuilder`. Therefore, // this skips using `f.debug_struct()`, since each one would force // a new layer of indentation. // // - In compact mode, a nested stack ends up just looking like a flat // list of layers. // // - In pretty mode, while a newline is inserted between each layer, // the `DebugStruct` used in the `ServiceBuilder` will inject padding // to that each line is at the same indentation level. // // Also, the order of [outer, inner] is important, since it reflects // the order that the layers were added to the stack. if f.alternate() { // pretty write!(f, "{:#?},\n{:#?}", self.outer, self.inner) } else { write!(f, "{:?}, {:?}", self.outer, self.inner) } } } tower-layer-0.3.2/src/tuple.rs000064400000000000000000000214151046102023000143710ustar 00000000000000use crate::Layer; impl Layer for () { type Service = S; fn layer(&self, service: S) -> Self::Service { service } } impl Layer for (L1,) where L1: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1,) = self; l1.layer(service) } } impl Layer for (L1, L2) where L1: Layer, L2: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2) = self; l1.layer(l2.layer(service)) } } impl Layer for (L1, L2, L3) where L1: Layer, L2: Layer, L3: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3) = self; l1.layer((l2, l3).layer(service)) } } impl Layer for (L1, L2, L3, L4) where L1: Layer, L2: Layer, L3: Layer, L4: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3, l4) = self; l1.layer((l2, l3, l4).layer(service)) } } impl Layer for (L1, L2, L3, L4, L5) where L1: Layer, L2: Layer, L3: Layer, L4: Layer, L5: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3, l4, l5) = self; l1.layer((l2, l3, l4, l5).layer(service)) } } impl Layer for (L1, L2, L3, L4, L5, L6) where L1: Layer, L2: Layer, L3: Layer, L4: Layer, L5: Layer, L6: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3, l4, l5, l6) = self; l1.layer((l2, l3, l4, l5, l6).layer(service)) } } impl Layer for (L1, L2, L3, L4, L5, L6, L7) where L1: Layer, L2: Layer, L3: Layer, L4: Layer, L5: Layer, L6: Layer, L7: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3, l4, l5, l6, l7) = self; l1.layer((l2, l3, l4, l5, l6, l7).layer(service)) } } impl Layer for (L1, L2, L3, L4, L5, L6, L7, L8) where L1: Layer, L2: Layer, L3: Layer, L4: Layer, L5: Layer, L6: Layer, L7: Layer, L8: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3, l4, l5, l6, l7, l8) = self; l1.layer((l2, l3, l4, l5, l6, l7, l8).layer(service)) } } impl Layer for (L1, L2, L3, L4, L5, L6, L7, L8, L9) where L1: Layer, L2: Layer, L3: Layer, L4: Layer, L5: Layer, L6: Layer, L7: Layer, L8: Layer, L9: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3, l4, l5, l6, l7, l8, l9) = self; l1.layer((l2, l3, l4, l5, l6, l7, l8, l9).layer(service)) } } impl Layer for (L1, L2, L3, L4, L5, L6, L7, L8, L9, L10) where L1: Layer, L2: Layer, L3: Layer, L4: Layer, L5: Layer, L6: Layer, L7: Layer, L8: Layer, L9: Layer, L10: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3, l4, l5, l6, l7, l8, l9, l10) = self; l1.layer((l2, l3, l4, l5, l6, l7, l8, l9, l10).layer(service)) } } impl Layer for (L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11) where L1: Layer, L2: Layer, L3: Layer, L4: Layer, L5: Layer, L6: Layer, L7: Layer, L8: Layer, L9: Layer, L10: Layer, L11: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11) = self; l1.layer((l2, l3, l4, l5, l6, l7, l8, l9, l10, l11).layer(service)) } } impl Layer for (L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12) where L1: Layer, L2: Layer, L3: Layer, L4: Layer, L5: Layer, L6: Layer, L7: Layer, L8: Layer, L9: Layer, L10: Layer, L11: Layer, L12: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12) = self; l1.layer((l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12).layer(service)) } } impl Layer for (L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13) where L1: Layer, L2: Layer, L3: Layer, L4: Layer, L5: Layer, L6: Layer, L7: Layer, L8: Layer, L9: Layer, L10: Layer, L11: Layer, L12: Layer, L13: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13) = self; l1.layer((l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13).layer(service)) } } impl Layer for (L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14) where L1: Layer, L2: Layer, L3: Layer, L4: Layer, L5: Layer, L6: Layer, L7: Layer, L8: Layer, L9: Layer, L10: Layer, L11: Layer, L12: Layer, L13: Layer, L14: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14) = self; l1.layer((l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14).layer(service)) } } #[rustfmt::skip] impl Layer for (L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15) where L1: Layer, L2: Layer, L3: Layer, L4: Layer, L5: Layer, L6: Layer, L7: Layer, L8: Layer, L9: Layer, L10: Layer, L11: Layer, L12: Layer, L13: Layer, L14: Layer, L15: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15) = self; l1.layer((l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15).layer(service)) } } #[rustfmt::skip] impl Layer for (L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15, L16) where L1: Layer, L2: Layer, L3: Layer, L4: Layer, L5: Layer, L6: Layer, L7: Layer, L8: Layer, L9: Layer, L10: Layer, L11: Layer, L12: Layer, L13: Layer, L14: Layer, L15: Layer, L16: Layer, { type Service = L1::Service; fn layer(&self, service: S) -> Self::Service { let (l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16) = self; l1.layer((l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16).layer(service)) } }