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}