Coverage Report

Created: 2026-03-23 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tower-0.5.2/src/builder/mod.rs
Line
Count
Source
1
//! Builder types to compose layers and services
2
3
use tower_layer::{Identity, Layer, Stack};
4
use tower_service::Service;
5
6
use std::fmt;
7
8
/// Declaratively construct [`Service`] values.
9
///
10
/// [`ServiceBuilder`] provides a [builder-like interface][builder] for composing
11
/// layers to be applied to a [`Service`].
12
///
13
/// # Service
14
///
15
/// A [`Service`] is a trait representing an asynchronous function of a request
16
/// to a response. It is similar to `async fn(Request) -> Result<Response, Error>`.
17
///
18
/// A [`Service`] is typically bound to a single transport, such as a TCP
19
/// connection.  It defines how _all_ inbound or outbound requests are handled
20
/// by that connection.
21
///
22
/// [builder]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
23
///
24
/// # Order
25
///
26
/// The order in which layers are added impacts how requests are handled. Layers
27
/// that are added first will be called with the request first. The argument to
28
/// `service` will be last to see the request.
29
///
30
/// ```
31
/// # // this (and other) doctest is ignored because we don't have a way
32
/// # // to say that it should only be run with cfg(feature = "...")
33
/// # use tower::Service;
34
/// # use tower::builder::ServiceBuilder;
35
/// # #[cfg(all(feature = "buffer", feature = "limit"))]
36
/// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
37
/// ServiceBuilder::new()
38
///     .buffer(100)
39
///     .concurrency_limit(10)
40
///     .service(svc)
41
/// # ;
42
/// # }
43
/// ```
44
///
45
/// In the above example, the buffer layer receives the request first followed
46
/// by `concurrency_limit`. `buffer` enables up to 100 request to be in-flight
47
/// **on top of** the requests that have already been forwarded to the next
48
/// layer. Combined with `concurrency_limit`, this allows up to 110 requests to be
49
/// in-flight.
50
///
51
/// ```
52
/// # use tower::Service;
53
/// # use tower::builder::ServiceBuilder;
54
/// # #[cfg(all(feature = "buffer", feature = "limit"))]
55
/// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
56
/// ServiceBuilder::new()
57
///     .concurrency_limit(10)
58
///     .buffer(100)
59
///     .service(svc)
60
/// # ;
61
/// # }
62
/// ```
63
///
64
/// The above example is similar, but the order of layers is reversed. Now,
65
/// `concurrency_limit` applies first and only allows 10 requests to be in-flight
66
/// total.
67
///
68
/// # Examples
69
///
70
/// A [`Service`] stack with a single layer:
71
///
72
/// ```
73
/// # use tower::Service;
74
/// # use tower::builder::ServiceBuilder;
75
/// # #[cfg(feature = "limit")]
76
/// # use tower::limit::concurrency::ConcurrencyLimitLayer;
77
/// # #[cfg(feature = "limit")]
78
/// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
79
/// ServiceBuilder::new()
80
///     .concurrency_limit(5)
81
///     .service(svc);
82
/// # ;
83
/// # }
84
/// ```
85
///
86
/// A [`Service`] stack with _multiple_ layers that contain rate limiting,
87
/// in-flight request limits, and a channel-backed, clonable [`Service`]:
88
///
89
/// ```
90
/// # use tower::Service;
91
/// # use tower::builder::ServiceBuilder;
92
/// # use std::time::Duration;
93
/// # #[cfg(all(feature = "buffer", feature = "limit"))]
94
/// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
95
/// ServiceBuilder::new()
96
///     .buffer(5)
97
///     .concurrency_limit(5)
98
///     .rate_limit(5, Duration::from_secs(1))
99
///     .service(svc);
100
/// # ;
101
/// # }
102
/// ```
103
///
104
/// [`Service`]: crate::Service
105
#[derive(Clone)]
106
pub struct ServiceBuilder<L> {
107
    layer: L,
108
}
109
110
impl Default for ServiceBuilder<Identity> {
111
0
    fn default() -> Self {
112
0
        Self::new()
113
0
    }
114
}
115
116
impl ServiceBuilder<Identity> {
117
    /// Create a new [`ServiceBuilder`].
118
0
    pub const fn new() -> Self {
119
0
        ServiceBuilder {
120
0
            layer: Identity::new(),
121
0
        }
122
0
    }
123
}
124
125
impl<L> ServiceBuilder<L> {
126
    /// Add a new layer `T` into the [`ServiceBuilder`].
127
    ///
128
    /// This wraps the inner service with the service provided by a user-defined
129
    /// [`Layer`]. The provided layer must implement the [`Layer`] trait.
130
    ///
131
    /// [`Layer`]: crate::Layer
132
0
    pub fn layer<T>(self, layer: T) -> ServiceBuilder<Stack<T, L>> {
133
0
        ServiceBuilder {
134
0
            layer: Stack::new(layer, self.layer),
135
0
        }
136
0
    }
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#0}>, tower_layer::identity::Identity>>>::layer::<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#1}>>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#2}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>>::layer::<tower::util::either::Either<tower::limit::concurrency::layer::ConcurrencyLimitLayer, tower_layer::identity::Identity>>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>::layer::<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#2}>>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#0}>, tower_layer::identity::Identity>>>::layer::<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#1}>>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#2}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>>::layer::<tower::util::either::Either<tower::limit::concurrency::layer::ConcurrencyLimitLayer, tower_layer::identity::Identity>>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>::layer::<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#2}>>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower::util::either::Either<tower::limit::concurrency::layer::ConcurrencyLimitLayer, tower_layer::identity::Identity>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#2}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>>>::layer::<tower::util::either::Either<tower::limit::rate::layer::RateLimitLayer, tower_layer::identity::Identity>>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower::util::either::Either<tower::limit::concurrency::layer::ConcurrencyLimitLayer, tower_layer::identity::Identity>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#2}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>>>::layer::<tower::util::either::Either<tower::limit::rate::layer::RateLimitLayer, tower_layer::identity::Identity>>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::identity::Identity>>::layer::<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#0}>>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::identity::Identity>>::layer::<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#0}>>
Unexecuted instantiation: <tower::builder::ServiceBuilder<_>>::layer::<_>
137
138
    /// Optionally add a new layer `T` into the [`ServiceBuilder`].
139
    ///
140
    /// ```
141
    /// # use std::time::Duration;
142
    /// # use tower::Service;
143
    /// # use tower::builder::ServiceBuilder;
144
    /// # use tower::timeout::TimeoutLayer;
145
    /// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
146
    /// # let timeout = Some(Duration::new(10, 0));
147
    /// // Apply a timeout if configured
148
    /// ServiceBuilder::new()
149
    ///     .option_layer(timeout.map(TimeoutLayer::new))
150
    ///     .service(svc)
151
    /// # ;
152
    /// # }
153
    /// ```
154
    #[cfg(feature = "util")]
155
0
    pub fn option_layer<T>(
156
0
        self,
157
0
        layer: Option<T>,
158
0
    ) -> ServiceBuilder<Stack<crate::util::Either<T, Identity>, L>> {
159
0
        self.layer(crate::util::option_layer(layer))
160
0
    }
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#2}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>>::option_layer::<tower::limit::concurrency::layer::ConcurrencyLimitLayer>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#2}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>>::option_layer::<tower::limit::concurrency::layer::ConcurrencyLimitLayer>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower::util::either::Either<tower::limit::concurrency::layer::ConcurrencyLimitLayer, tower_layer::identity::Identity>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#2}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>>>::option_layer::<tower::limit::rate::layer::RateLimitLayer>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower::util::either::Either<tower::limit::concurrency::layer::ConcurrencyLimitLayer, tower_layer::identity::Identity>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#2}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>>>::option_layer::<tower::limit::rate::layer::RateLimitLayer>
Unexecuted instantiation: <tower::builder::ServiceBuilder<_>>::option_layer::<_>
161
162
    /// Add a [`Layer`] built from a function that accepts a service and returns another service.
163
    ///
164
    /// See the documentation for [`layer_fn`] for more details.
165
    ///
166
    /// [`layer_fn`]: crate::layer::layer_fn
167
0
    pub fn layer_fn<F>(self, f: F) -> ServiceBuilder<Stack<crate::layer::LayerFn<F>, L>> {
168
0
        self.layer(crate::layer::layer_fn(f))
169
0
    }
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#0}>, tower_layer::identity::Identity>>>::layer_fn::<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#1}>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>::layer_fn::<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#2}>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#0}>, tower_layer::identity::Identity>>>::layer_fn::<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#1}>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>::layer_fn::<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#2}>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::identity::Identity>>::layer_fn::<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#0}>
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::identity::Identity>>::layer_fn::<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#0}>
Unexecuted instantiation: <tower::builder::ServiceBuilder<_>>::layer_fn::<_>
170
171
    /// Buffer requests when the next layer is not ready.
172
    ///
173
    /// This wraps the inner service with an instance of the [`Buffer`]
174
    /// middleware.
175
    ///
176
    /// [`Buffer`]: crate::buffer
177
    #[cfg(feature = "buffer")]
178
0
    pub fn buffer<Request>(
179
0
        self,
180
0
        bound: usize,
181
0
    ) -> ServiceBuilder<Stack<crate::buffer::BufferLayer<Request>, L>> {
182
0
        self.layer(crate::buffer::BufferLayer::new(bound))
183
0
    }
184
185
    /// Limit the max number of in-flight requests.
186
    ///
187
    /// A request is in-flight from the time the request is received until the
188
    /// response future completes. This includes the time spent in the next
189
    /// layers.
190
    ///
191
    /// This wraps the inner service with an instance of the
192
    /// [`ConcurrencyLimit`] middleware.
193
    ///
194
    /// [`ConcurrencyLimit`]: crate::limit::concurrency
195
    #[cfg(feature = "limit")]
196
0
    pub fn concurrency_limit(
197
0
        self,
198
0
        max: usize,
199
0
    ) -> ServiceBuilder<Stack<crate::limit::ConcurrencyLimitLayer, L>> {
200
0
        self.layer(crate::limit::ConcurrencyLimitLayer::new(max))
201
0
    }
202
203
    /// Drop requests when the next layer is unable to respond to requests.
204
    ///
205
    /// Usually, when a service or middleware does not have capacity to process a
206
    /// request (i.e., [`poll_ready`] returns [`Pending`]), the caller waits until
207
    /// capacity becomes available.
208
    ///
209
    /// [`LoadShed`] immediately responds with an error when the next layer is
210
    /// out of capacity.
211
    ///
212
    /// This wraps the inner service with an instance of the [`LoadShed`]
213
    /// middleware.
214
    ///
215
    /// [`LoadShed`]: crate::load_shed
216
    /// [`poll_ready`]: crate::Service::poll_ready
217
    /// [`Pending`]: std::task::Poll::Pending
218
    #[cfg(feature = "load-shed")]
219
0
    pub fn load_shed(self) -> ServiceBuilder<Stack<crate::load_shed::LoadShedLayer, L>> {
220
0
        self.layer(crate::load_shed::LoadShedLayer::new())
221
0
    }
222
223
    /// Limit requests to at most `num` per the given duration.
224
    ///
225
    /// This wraps the inner service with an instance of the [`RateLimit`]
226
    /// middleware.
227
    ///
228
    /// [`RateLimit`]: crate::limit::rate
229
    #[cfg(feature = "limit")]
230
0
    pub fn rate_limit(
231
0
        self,
232
0
        num: u64,
233
0
        per: std::time::Duration,
234
0
    ) -> ServiceBuilder<Stack<crate::limit::RateLimitLayer, L>> {
235
0
        self.layer(crate::limit::RateLimitLayer::new(num, per))
236
0
    }
237
238
    /// Retry failed requests according to the given [retry policy][policy].
239
    ///
240
    /// `policy` determines which failed requests will be retried. It must
241
    /// implement the [`retry::Policy`][policy] trait.
242
    ///
243
    /// This wraps the inner service with an instance of the [`Retry`]
244
    /// middleware.
245
    ///
246
    /// [`Retry`]: crate::retry
247
    /// [policy]: crate::retry::Policy
248
    #[cfg(feature = "retry")]
249
    pub fn retry<P>(self, policy: P) -> ServiceBuilder<Stack<crate::retry::RetryLayer<P>, L>> {
250
        self.layer(crate::retry::RetryLayer::new(policy))
251
    }
252
253
    /// Fail requests that take longer than `timeout`.
254
    ///
255
    /// If the next layer takes more than `timeout` to respond to a request,
256
    /// processing is terminated and an error is returned.
257
    ///
258
    /// This wraps the inner service with an instance of the [`timeout`]
259
    /// middleware.
260
    ///
261
    /// [`timeout`]: crate::timeout
262
    #[cfg(feature = "timeout")]
263
    pub fn timeout(
264
        self,
265
        timeout: std::time::Duration,
266
    ) -> ServiceBuilder<Stack<crate::timeout::TimeoutLayer, L>> {
267
        self.layer(crate::timeout::TimeoutLayer::new(timeout))
268
    }
269
270
    /// Conditionally reject requests based on `predicate`.
271
    ///
272
    /// `predicate` must implement the [`Predicate`] trait.
273
    ///
274
    /// This wraps the inner service with an instance of the [`Filter`]
275
    /// middleware.
276
    ///
277
    /// [`Filter`]: crate::filter
278
    /// [`Predicate`]: crate::filter::Predicate
279
    #[cfg(feature = "filter")]
280
    pub fn filter<P>(
281
        self,
282
        predicate: P,
283
    ) -> ServiceBuilder<Stack<crate::filter::FilterLayer<P>, L>> {
284
        self.layer(crate::filter::FilterLayer::new(predicate))
285
    }
286
287
    /// Conditionally reject requests based on an asynchronous `predicate`.
288
    ///
289
    /// `predicate` must implement the [`AsyncPredicate`] trait.
290
    ///
291
    /// This wraps the inner service with an instance of the [`AsyncFilter`]
292
    /// middleware.
293
    ///
294
    /// [`AsyncFilter`]: crate::filter::AsyncFilter
295
    /// [`AsyncPredicate`]: crate::filter::AsyncPredicate
296
    #[cfg(feature = "filter")]
297
    pub fn filter_async<P>(
298
        self,
299
        predicate: P,
300
    ) -> ServiceBuilder<Stack<crate::filter::AsyncFilterLayer<P>, L>> {
301
        self.layer(crate::filter::AsyncFilterLayer::new(predicate))
302
    }
303
304
    /// Map one request type to another.
305
    ///
306
    /// This wraps the inner service with an instance of the [`MapRequest`]
307
    /// middleware.
308
    ///
309
    /// # Examples
310
    ///
311
    /// Changing the type of a request:
312
    ///
313
    /// ```rust
314
    /// use tower::ServiceBuilder;
315
    /// use tower::ServiceExt;
316
    ///
317
    /// # #[tokio::main]
318
    /// # async fn main() -> Result<(), ()> {
319
    /// // Suppose we have some `Service` whose request type is `String`:
320
    /// let string_svc = tower::service_fn(|request: String| async move {
321
    ///     println!("request: {}", request);
322
    ///     Ok(())
323
    /// });
324
    ///
325
    /// // ...but we want to call that service with a `usize`. What do we do?
326
    ///
327
    /// let usize_svc = ServiceBuilder::new()
328
    ///      // Add a middleware that converts the request type to a `String`:
329
    ///     .map_request(|request: usize| format!("{}", request))
330
    ///     // ...and wrap the string service with that middleware:
331
    ///     .service(string_svc);
332
    ///
333
    /// // Now, we can call that service with a `usize`:
334
    /// usize_svc.oneshot(42).await?;
335
    /// # Ok(())
336
    /// # }
337
    /// ```
338
    ///
339
    /// Modifying the request value:
340
    ///
341
    /// ```rust
342
    /// use tower::ServiceBuilder;
343
    /// use tower::ServiceExt;
344
    ///
345
    /// # #[tokio::main]
346
    /// # async fn main() -> Result<(), ()> {
347
    /// // A service that takes a number and returns it:
348
    /// let svc = tower::service_fn(|request: usize| async move {
349
    ///    Ok(request)
350
    /// });
351
    ///
352
    /// let svc = ServiceBuilder::new()
353
    ///      // Add a middleware that adds 1 to each request
354
    ///     .map_request(|request: usize| request + 1)
355
    ///     .service(svc);
356
    ///
357
    /// let response = svc.oneshot(1).await?;
358
    /// assert_eq!(response, 2);
359
    /// # Ok(())
360
    /// # }
361
    /// ```
362
    ///
363
    /// [`MapRequest`]: crate::util::MapRequest
364
    #[cfg(feature = "util")]
365
0
    pub fn map_request<F, R1, R2>(
366
0
        self,
367
0
        f: F,
368
0
    ) -> ServiceBuilder<Stack<crate::util::MapRequestLayer<F>, L>>
369
0
    where
370
0
        F: FnMut(R1) -> R2 + Clone,
371
    {
372
0
        self.layer(crate::util::MapRequestLayer::new(f))
373
0
    }
374
375
    /// Map one response type to another.
376
    ///
377
    /// This wraps the inner service with an instance of the [`MapResponse`]
378
    /// middleware.
379
    ///
380
    /// See the documentation for the [`map_response` combinator] for details.
381
    ///
382
    /// [`MapResponse`]: crate::util::MapResponse
383
    /// [`map_response` combinator]: crate::util::ServiceExt::map_response
384
    #[cfg(feature = "util")]
385
0
    pub fn map_response<F>(
386
0
        self,
387
0
        f: F,
388
0
    ) -> ServiceBuilder<Stack<crate::util::MapResponseLayer<F>, L>> {
389
0
        self.layer(crate::util::MapResponseLayer::new(f))
390
0
    }
391
392
    /// Map one error type to another.
393
    ///
394
    /// This wraps the inner service with an instance of the [`MapErr`]
395
    /// middleware.
396
    ///
397
    /// See the documentation for the [`map_err` combinator] for details.
398
    ///
399
    /// [`MapErr`]: crate::util::MapErr
400
    /// [`map_err` combinator]: crate::util::ServiceExt::map_err
401
    #[cfg(feature = "util")]
402
0
    pub fn map_err<F>(self, f: F) -> ServiceBuilder<Stack<crate::util::MapErrLayer<F>, L>> {
403
0
        self.layer(crate::util::MapErrLayer::new(f))
404
0
    }
405
406
    /// Composes a function that transforms futures produced by the service.
407
    ///
408
    /// This wraps the inner service with an instance of the [`MapFutureLayer`] middleware.
409
    ///
410
    /// See the documentation for the [`map_future`] combinator for details.
411
    ///
412
    /// [`MapFutureLayer`]: crate::util::MapFutureLayer
413
    /// [`map_future`]: crate::util::ServiceExt::map_future
414
    #[cfg(feature = "util")]
415
0
    pub fn map_future<F>(self, f: F) -> ServiceBuilder<Stack<crate::util::MapFutureLayer<F>, L>> {
416
0
        self.layer(crate::util::MapFutureLayer::new(f))
417
0
    }
418
419
    /// Apply an asynchronous function after the service, regardless of whether the future
420
    /// succeeds or fails.
421
    ///
422
    /// This wraps the inner service with an instance of the [`Then`]
423
    /// middleware.
424
    ///
425
    /// This is similar to the [`map_response`] and [`map_err`] functions,
426
    /// except that the *same* function is invoked when the service's future
427
    /// completes, whether it completes successfully or fails. This function
428
    /// takes the [`Result`] returned by the service's future, and returns a
429
    /// [`Result`].
430
    ///
431
    /// See the documentation for the [`then` combinator] for details.
432
    ///
433
    /// [`Then`]: crate::util::Then
434
    /// [`then` combinator]: crate::util::ServiceExt::then
435
    /// [`map_response`]: ServiceBuilder::map_response
436
    /// [`map_err`]: ServiceBuilder::map_err
437
    #[cfg(feature = "util")]
438
0
    pub fn then<F>(self, f: F) -> ServiceBuilder<Stack<crate::util::ThenLayer<F>, L>> {
439
0
        self.layer(crate::util::ThenLayer::new(f))
440
0
    }
441
442
    /// Executes a new future after this service's future resolves. This does
443
    /// not alter the behaviour of the [`poll_ready`] method.
444
    ///
445
    /// This method can be used to change the [`Response`] type of the service
446
    /// into a different type. You can use this method to chain along a computation once the
447
    /// service's response has been resolved.
448
    ///
449
    /// This wraps the inner service with an instance of the [`AndThen`]
450
    /// middleware.
451
    ///
452
    /// See the documentation for the [`and_then` combinator] for details.
453
    ///
454
    /// [`Response`]: crate::Service::Response
455
    /// [`poll_ready`]: crate::Service::poll_ready
456
    /// [`and_then` combinator]: crate::util::ServiceExt::and_then
457
    /// [`AndThen`]: crate::util::AndThen
458
    #[cfg(feature = "util")]
459
0
    pub fn and_then<F>(self, f: F) -> ServiceBuilder<Stack<crate::util::AndThenLayer<F>, L>> {
460
0
        self.layer(crate::util::AndThenLayer::new(f))
461
0
    }
462
463
    /// Maps this service's result type (`Result<Self::Response, Self::Error>`)
464
    /// to a different value, regardless of whether the future succeeds or
465
    /// fails.
466
    ///
467
    /// This wraps the inner service with an instance of the [`MapResult`]
468
    /// middleware.
469
    ///
470
    /// See the documentation for the [`map_result` combinator] for details.
471
    ///
472
    /// [`map_result` combinator]: crate::util::ServiceExt::map_result
473
    /// [`MapResult`]: crate::util::MapResult
474
    #[cfg(feature = "util")]
475
0
    pub fn map_result<F>(self, f: F) -> ServiceBuilder<Stack<crate::util::MapResultLayer<F>, L>> {
476
0
        self.layer(crate::util::MapResultLayer::new(f))
477
0
    }
478
479
    /// Returns the underlying `Layer` implementation.
480
0
    pub fn into_inner(self) -> L {
481
0
        self.layer
482
0
    }
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower::util::either::Either<tower::limit::rate::layer::RateLimitLayer, tower_layer::identity::Identity>, tower_layer::stack::Stack<tower::util::either::Either<tower::limit::concurrency::layer::ConcurrencyLimitLayer, tower_layer::identity::Identity>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#2}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>>>>::into_inner
Unexecuted instantiation: <tower::builder::ServiceBuilder<tower_layer::stack::Stack<tower::util::either::Either<tower::limit::rate::layer::RateLimitLayer, tower_layer::identity::Identity>, tower_layer::stack::Stack<tower::util::either::Either<tower::limit::concurrency::layer::ConcurrencyLimitLayer, tower_layer::identity::Identity>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#2}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#1}>, tower_layer::stack::Stack<tower_layer::layer_fn::LayerFn<<tonic::transport::channel::service::connection::Connection>::new<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>::{closure#0}>, tower_layer::identity::Identity>>>>>>>::into_inner
Unexecuted instantiation: <tower::builder::ServiceBuilder<_>>::into_inner
483
484
    /// Wrap the service `S` with the middleware provided by this
485
    /// [`ServiceBuilder`]'s [`Layer`]'s, returning a new [`Service`].
486
    ///
487
    /// [`Layer`]: crate::Layer
488
    /// [`Service`]: crate::Service
489
0
    pub fn service<S>(&self, service: S) -> L::Service
490
0
    where
491
0
        L: Layer<S>,
492
    {
493
0
        self.layer.layer(service)
494
0
    }
495
496
    /// Wrap the async function `F` with the middleware provided by this [`ServiceBuilder`]'s
497
    /// [`Layer`]s, returning a new [`Service`].
498
    ///
499
    /// This is a convenience method which is equivalent to calling
500
    /// [`ServiceBuilder::service`] with a [`service_fn`], like this:
501
    ///
502
    /// ```rust
503
    /// # use tower::{ServiceBuilder, service_fn};
504
    /// # async fn handler_fn(_: ()) -> Result<(), ()> { Ok(()) }
505
    /// # let _ = {
506
    /// ServiceBuilder::new()
507
    ///     // ...
508
    ///     .service(service_fn(handler_fn))
509
    /// # };
510
    /// ```
511
    ///
512
    /// # Example
513
    ///
514
    /// ```rust
515
    /// use std::time::Duration;
516
    /// use tower::{ServiceBuilder, ServiceExt, BoxError, service_fn};
517
    ///
518
    /// # #[tokio::main]
519
    /// # async fn main() -> Result<(), BoxError> {
520
    /// async fn handle(request: &'static str) -> Result<&'static str, BoxError> {
521
    ///    Ok(request)
522
    /// }
523
    ///
524
    /// let svc = ServiceBuilder::new()
525
    ///     .buffer(1024)
526
    ///     .timeout(Duration::from_secs(10))
527
    ///     .service_fn(handle);
528
    ///
529
    /// let response = svc.oneshot("foo").await?;
530
    ///
531
    /// assert_eq!(response, "foo");
532
    /// # Ok(())
533
    /// # }
534
    /// ```
535
    ///
536
    /// [`Layer`]: crate::Layer
537
    /// [`Service`]: crate::Service
538
    /// [`service_fn`]: crate::service_fn
539
    #[cfg(feature = "util")]
540
0
    pub fn service_fn<F>(self, f: F) -> L::Service
541
0
    where
542
0
        L: Layer<crate::util::ServiceFn<F>>,
543
    {
544
0
        self.service(crate::util::service_fn(f))
545
0
    }
546
547
    /// Check that the builder implements `Clone`.
548
    ///
549
    /// This can be useful when debugging type errors in `ServiceBuilder`s with lots of layers.
550
    ///
551
    /// Doesn't actually change the builder but serves as a type check.
552
    ///
553
    /// # Example
554
    ///
555
    /// ```rust
556
    /// use tower::ServiceBuilder;
557
    ///
558
    /// let builder = ServiceBuilder::new()
559
    ///     // Do something before processing the request
560
    ///     .map_request(|request: String| {
561
    ///         println!("got request!");
562
    ///         request
563
    ///     })
564
    ///     // Ensure our `ServiceBuilder` can be cloned
565
    ///     .check_clone()
566
    ///     // Do something after processing the request
567
    ///     .map_response(|response: String| {
568
    ///         println!("got response!");
569
    ///         response
570
    ///     });
571
    /// ```
572
    #[inline]
573
0
    pub fn check_clone(self) -> Self
574
0
    where
575
0
        Self: Clone,
576
    {
577
0
        self
578
0
    }
579
580
    /// Check that the builder when given a service of type `S` produces a service that implements
581
    /// `Clone`.
582
    ///
583
    /// This can be useful when debugging type errors in `ServiceBuilder`s with lots of layers.
584
    ///
585
    /// Doesn't actually change the builder but serves as a type check.
586
    ///
587
    /// # Example
588
    ///
589
    /// ```rust
590
    /// use tower::ServiceBuilder;
591
    ///
592
    /// # #[derive(Clone)]
593
    /// # struct MyService;
594
    /// #
595
    /// let builder = ServiceBuilder::new()
596
    ///     // Do something before processing the request
597
    ///     .map_request(|request: String| {
598
    ///         println!("got request!");
599
    ///         request
600
    ///     })
601
    ///     // Ensure that the service produced when given a `MyService` implements
602
    ///     .check_service_clone::<MyService>()
603
    ///     // Do something after processing the request
604
    ///     .map_response(|response: String| {
605
    ///         println!("got response!");
606
    ///         response
607
    ///     });
608
    /// ```
609
    #[inline]
610
0
    pub fn check_service_clone<S>(self) -> Self
611
0
    where
612
0
        L: Layer<S>,
613
0
        L::Service: Clone,
614
    {
615
0
        self
616
0
    }
617
618
    /// Check that the builder when given a service of type `S` produces a service with the given
619
    /// request, response, and error types.
620
    ///
621
    /// This can be useful when debugging type errors in `ServiceBuilder`s with lots of layers.
622
    ///
623
    /// Doesn't actually change the builder but serves as a type check.
624
    ///
625
    /// # Example
626
    ///
627
    /// ```rust
628
    /// use tower::ServiceBuilder;
629
    /// use std::task::{Poll, Context};
630
    /// use tower::{Service, ServiceExt};
631
    ///
632
    /// // An example service
633
    /// struct MyService;
634
    ///
635
    /// impl Service<Request> for MyService {
636
    ///   type Response = Response;
637
    ///   type Error = Error;
638
    ///   type Future = futures_util::future::Ready<Result<Response, Error>>;
639
    ///
640
    ///   fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
641
    ///       // ...
642
    ///       # todo!()
643
    ///   }
644
    ///
645
    ///   fn call(&mut self, request: Request) -> Self::Future {
646
    ///       // ...
647
    ///       # todo!()
648
    ///   }
649
    /// }
650
    ///
651
    /// struct Request;
652
    /// struct Response;
653
    /// struct Error;
654
    ///
655
    /// struct WrappedResponse(Response);
656
    ///
657
    /// let builder = ServiceBuilder::new()
658
    ///     // At this point in the builder if given a `MyService` it produces a service that
659
    ///     // accepts `Request`s, produces `Response`s, and fails with `Error`s
660
    ///     .check_service::<MyService, Request, Response, Error>()
661
    ///     // Wrap responses in `WrappedResponse`
662
    ///     .map_response(|response: Response| WrappedResponse(response))
663
    ///     // Now the response type will be `WrappedResponse`
664
    ///     .check_service::<MyService, _, WrappedResponse, _>();
665
    /// ```
666
    #[inline]
667
0
    pub fn check_service<S, T, U, E>(self) -> Self
668
0
    where
669
0
        L: Layer<S>,
670
0
        L::Service: Service<T, Response = U, Error = E>,
671
    {
672
0
        self
673
0
    }
674
675
    /// This wraps the inner service with the [`Layer`] returned by [`BoxService::layer()`].
676
    ///
677
    /// See that method for more details.
678
    ///
679
    /// # Example
680
    ///
681
    /// ```
682
    /// use tower::{Service, ServiceBuilder, BoxError, util::BoxService};
683
    /// use std::time::Duration;
684
    /// #
685
    /// # struct Request;
686
    /// # struct Response;
687
    /// # impl Response {
688
    /// #     fn new() -> Self { Self }
689
    /// # }
690
    ///
691
    /// let service: BoxService<Request, Response, BoxError> = ServiceBuilder::new()
692
    ///     .boxed()
693
    ///     .load_shed()
694
    ///     .concurrency_limit(64)
695
    ///     .timeout(Duration::from_secs(10))
696
    ///     .service_fn(|req: Request| async {
697
    ///         Ok::<_, BoxError>(Response::new())
698
    ///     });
699
    /// # let service = assert_service(service);
700
    /// # fn assert_service<S, R>(svc: S) -> S
701
    /// # where S: Service<R> { svc }
702
    /// ```
703
    ///
704
    /// [`BoxService::layer()`]: crate::util::BoxService::layer()
705
    #[cfg(feature = "util")]
706
0
    pub fn boxed<S, R>(
707
0
        self,
708
0
    ) -> ServiceBuilder<
709
0
        Stack<
710
0
            tower_layer::LayerFn<
711
0
                fn(
712
0
                    L::Service,
713
0
                ) -> crate::util::BoxService<
714
0
                    R,
715
0
                    <L::Service as Service<R>>::Response,
716
0
                    <L::Service as Service<R>>::Error,
717
0
                >,
718
0
            >,
719
0
            L,
720
0
        >,
721
0
    >
722
0
    where
723
0
        L: Layer<S>,
724
0
        L::Service: Service<R> + Send + 'static,
725
0
        <L::Service as Service<R>>::Future: Send + 'static,
726
    {
727
0
        self.layer(crate::util::BoxService::layer())
728
0
    }
729
730
    /// This wraps the inner service with the [`Layer`] returned by [`BoxCloneService::layer()`].
731
    ///
732
    /// This is similar to the [`boxed`] method, but it requires that `Self` implement
733
    /// [`Clone`], and the returned boxed service implements [`Clone`].
734
    ///
735
    /// See [`BoxCloneService`] for more details.
736
    ///
737
    /// # Example
738
    ///
739
    /// ```
740
    /// use tower::{Service, ServiceBuilder, BoxError, util::BoxCloneService};
741
    /// use std::time::Duration;
742
    /// #
743
    /// # struct Request;
744
    /// # struct Response;
745
    /// # impl Response {
746
    /// #     fn new() -> Self { Self }
747
    /// # }
748
    ///
749
    /// let service: BoxCloneService<Request, Response, BoxError> = ServiceBuilder::new()
750
    ///     .boxed_clone()
751
    ///     .load_shed()
752
    ///     .concurrency_limit(64)
753
    ///     .timeout(Duration::from_secs(10))
754
    ///     .service_fn(|req: Request| async {
755
    ///         Ok::<_, BoxError>(Response::new())
756
    ///     });
757
    /// # let service = assert_service(service);
758
    ///
759
    /// // The boxed service can still be cloned.
760
    /// service.clone();
761
    /// # fn assert_service<S, R>(svc: S) -> S
762
    /// # where S: Service<R> { svc }
763
    /// ```
764
    ///
765
    /// [`BoxCloneService::layer()`]: crate::util::BoxCloneService::layer()
766
    /// [`BoxCloneService`]: crate::util::BoxCloneService
767
    /// [`boxed`]: Self::boxed
768
    #[cfg(feature = "util")]
769
0
    pub fn boxed_clone<S, R>(
770
0
        self,
771
0
    ) -> ServiceBuilder<
772
0
        Stack<
773
0
            tower_layer::LayerFn<
774
0
                fn(
775
0
                    L::Service,
776
0
                ) -> crate::util::BoxCloneService<
777
0
                    R,
778
0
                    <L::Service as Service<R>>::Response,
779
0
                    <L::Service as Service<R>>::Error,
780
0
                >,
781
0
            >,
782
0
            L,
783
0
        >,
784
0
    >
785
0
    where
786
0
        L: Layer<S>,
787
0
        L::Service: Service<R> + Clone + Send + 'static,
788
0
        <L::Service as Service<R>>::Future: Send + 'static,
789
    {
790
0
        self.layer(crate::util::BoxCloneService::layer())
791
0
    }
792
}
793
794
impl<L: fmt::Debug> fmt::Debug for ServiceBuilder<L> {
795
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
796
0
        f.debug_tuple("ServiceBuilder").field(&self.layer).finish()
797
0
    }
798
}
799
800
impl<S, L> Layer<S> for ServiceBuilder<L>
801
where
802
    L: Layer<S>,
803
{
804
    type Service = L::Service;
805
806
0
    fn layer(&self, inner: S) -> Self::Service {
807
0
        self.layer.layer(inner)
808
0
    }
809
}