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