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/latest/tower/trait.Service.html
18 
19 mod identity;
20 mod layer_fn;
21 mod stack;
22 mod tuple;
23 
24 pub 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/latest/tower/trait.Service.html
95 pub 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.
layer(&self, inner: S) -> Self::Service100     fn layer(&self, inner: S) -> Self::Service;
101 }
102 
103 impl<'a, T, S> Layer<S> for &'a T
104 where
105     T: ?Sized + Layer<S>,
106 {
107     type Service = T::Service;
108 
layer(&self, inner: S) -> Self::Service109     fn layer(&self, inner: S) -> Self::Service {
110         (**self).layer(inner)
111     }
112 }
113