tower_layer/
lib.rs

1#![warn(
2    missing_debug_implementations,
3    missing_docs,
4    rust_2018_idioms,
5    unreachable_pub
6)]
7#![forbid(unsafe_code)]
8// `rustdoc::broken_intra_doc_links` is checked on CI
9
10//! Layer traits and extensions.
11//!
12//! A layer decorates an service and provides additional functionality. It
13//! allows other services to be composed with the service that implements layer.
14//!
15//! A middleware implements the [`Layer`] and [`Service`] trait.
16//!
17//! [`Service`]: https://docs.rs/tower/*/tower/trait.Service.html
18
19#![no_std]
20
21#[cfg(test)]
22extern crate alloc;
23
24mod identity;
25mod layer_fn;
26mod stack;
27mod tuple;
28
29pub use self::{
30    identity::Identity,
31    layer_fn::{layer_fn, LayerFn},
32    stack::Stack,
33};
34
35/// Decorates a [`Service`], transforming either the request or the response.
36///
37/// Often, many of the pieces needed for writing network applications can be
38/// reused across multiple services. The `Layer` trait can be used to write
39/// reusable components that can be applied to very different kinds of services;
40/// for example, it can be applied to services operating on different protocols,
41/// and to both the client and server side of a network transaction.
42///
43/// # Log
44///
45/// Take request logging as an example:
46///
47/// ```rust
48/// # use tower_service::Service;
49/// # use core::task::{Poll, Context};
50/// # use tower_layer::Layer;
51/// # use core::fmt;
52///
53/// pub struct LogLayer {
54///     target: &'static str,
55/// }
56///
57/// impl<S> Layer<S> for LogLayer {
58///     type Service = LogService<S>;
59///
60///     fn layer(&self, service: S) -> Self::Service {
61///         LogService {
62///             target: self.target,
63///             service
64///         }
65///     }
66/// }
67///
68/// // This service implements the Log behavior
69/// pub struct LogService<S> {
70///     target: &'static str,
71///     service: S,
72/// }
73///
74/// impl<S, Request> Service<Request> for LogService<S>
75/// where
76///     S: Service<Request>,
77///     Request: fmt::Debug,
78/// {
79///     type Response = S::Response;
80///     type Error = S::Error;
81///     type Future = S::Future;
82///
83///     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
84///         self.service.poll_ready(cx)
85///     }
86///
87///     fn call(&mut self, request: Request) -> Self::Future {
88///         // Insert log statement here or other functionality
89///         println!("request = {:?}, target = {:?}", request, self.target);
90///         self.service.call(request)
91///     }
92/// }
93/// ```
94///
95/// The above log implementation is decoupled from the underlying protocol and
96/// is also decoupled from client or server concerns. In other words, the same
97/// log middleware could be used in either a client or a server.
98///
99/// [`Service`]: https://docs.rs/tower/*/tower/trait.Service.html
100pub trait Layer<S> {
101    /// The wrapped service
102    type Service;
103    /// Wrap the given service with the middleware, returning a new service
104    /// that has been decorated with the middleware.
105    fn layer(&self, inner: S) -> Self::Service;
106}
107
108impl<T, S> Layer<S> for &T
109where
110    T: ?Sized + Layer<S>,
111{
112    type Service = T::Service;
113
114    fn layer(&self, inner: S) -> Self::Service {
115        (**self).layer(inner)
116    }
117}