Coverage Report

Created: 2025-05-07 06:59

/rust/registry/src/index.crates.io-6f17d22bba15001f/tower-layer-0.3.3/src/lib.rs
Line
Count
Source (jump to first uncovered line)
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
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/*/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.
100
    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
109
0
    fn layer(&self, inner: S) -> Self::Service {
110
0
        (**self).layer(inner)
111
0
    }
112
}