1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
use ;
use crate;
use crate::;
/// Applies middleware to every service produced by a factory.
///
/// Returns a [`ServiceChainFactory`] containing an [`ApplyMiddleware`].
/// Creation first awaits the inner factory, then calls [`Middleware::create`]
/// synchronously with the new service and the same state reference. If the
/// factory fails, its initialization error is returned without invoking the
/// middleware.
///
/// To use the result as a [`ServiceFactory`], the middleware's service must
/// accept the same state and request types as the inner service. Response and
/// service-error types may change. The wrapper is responsible for forwarding
/// calls, binding, readiness, and shutdown as appropriate.
///
/// Cloning the resulting factory shares the middleware and inner factory
/// through [`Rc`]; neither needs to implement [`Clone`].
///
/// # Example
///
/// ```
/// use ntex_service::{Identity, apply, fn_factory, fn_service};
///
/// # async fn example() -> Result<(), ()> {
/// let factory = apply(
/// Identity,
/// fn_factory(async |offset: &u32| {
/// let offset = *offset;
/// Ok::<_, ()>(fn_service(async move |req: u32| Ok::<_, ()>(req + offset)))
/// }),
/// );
///
/// let pipeline = factory.pipeline(10).await?;
/// assert_eq!(pipeline.call(2).await?, 12);
/// # Ok(())
/// # }
/// ```
/// Wraps an inner service during service construction.
///
/// [`Self::create`] takes ownership of an already-created service and returns
/// a wrapper synchronously and infallibly. The wrapper can run work before
/// and after inner calls, transform requests, responses, or errors, or avoid
/// calling the inner service.
///
/// Use [`apply()`], [`Self::apply_to`], or [`ServiceChainFactory::apply`] to
/// install middleware on a factory. These require the wrapper to implement
/// [`Service`] for the factory's state and request types. Direct use of
/// [`Self::create`] can also construct wrappers with a different request type.
///
/// The state reference is available during construction. A service wrapper
/// can access the current state on each call through [`crate::Ctx::st`].
/// [`Rc`] middleware shares one middleware value across its clones, and
/// [`Stack`] composes multiple wrappers.
///
/// # Choosing an approach
///
/// - Use [`fn_layer`] for logic that runs before or after the inner call.
/// Binding, readiness, and shutdown are forwarded automatically.
/// - Implement this trait with a wrapper [`Service`] when the wrapper owns
/// its own readiness source, keeps per-service state, or needs a named type.
/// Forward lifecycle methods with [`crate::forward!`].
///
/// # Lifecycle forwarding
///
/// Middleware must arrange the resulting service's lifecycle behavior.
/// Wrappers retaining an inner service should forward [`Service::bind`] so
/// its readiness notifications reach the enclosing pipeline, and forward or
/// deliberately replace its readiness and shutdown behavior. These methods
/// are not forwarded automatically by implementing this trait.
///
/// # Example
///
/// For example, timeout middleware:
///
/// ```rust
/// use ntex_service::{Ctx, Service};
/// use ntex::{time::sleep, util::Either, util::select};
///
/// pub struct Timeout<S> {
/// service: S,
/// timeout: std::time::Duration,
/// }
///
/// pub enum TimeoutError<E> {
/// Service(E),
/// Timeout,
/// }
///
/// impl<S, R> Service<(), R> for Timeout<S>
/// where
/// S: Service<(), R>,
/// {
/// type Res = S::Res;
/// type Error = TimeoutError<S::Error>;
///
/// ntex_service::forward!((), service, map_err = TimeoutError::Service);
///
/// async fn call(&self, req: R, ctx: Ctx<'_, Self>) -> Result<Self::Res, Self::Error> {
/// match select(sleep(self.timeout), ctx.call(&self.service, req)).await {
/// Either::Left(_) => Err(TimeoutError::Timeout),
/// Either::Right(res) => res.map_err(TimeoutError::Service),
/// }
/// }
/// }
/// ```
///
/// The timeout service is independent of the wrapped service implementation and
/// can be applied to any compatible service.
///
/// Middleware that constructs `Timeout` could look like this:
///
/// ```rust
/// # use ntex_service::Middleware;
/// # pub struct Timeout<S> {
/// # service: S,
/// # timeout: std::time::Duration,
/// # }
/// pub struct TimeoutMiddleware {
/// timeout: std::time::Duration,
/// }
///
/// impl<S> Middleware<S, ()> for TimeoutMiddleware
/// {
/// type Service = Timeout<S>;
///
/// fn create(&self, _: &(), service: S) -> Self::Service {
/// Timeout {
/// service,
/// timeout: self.timeout,
/// }
/// }
/// }
/// ```
/// A service factory with middleware applied.
///
/// Created by [`apply()`], [`Middleware::apply_to`], or
/// [`ServiceChainFactory::apply`]. Each creation first awaits the inner
/// factory, then wraps its service through [`Middleware::create`] with the
/// same state reference.
///
/// The wrapper determines response and service-error types and is responsible
/// for lifecycle forwarding. Inner initialization errors are returned
/// unchanged without invoking the middleware.
///
/// Cloning shares both middleware and factory through [`Rc`] rather than
/// cloning them or creating a service.
>);
/// Middleware that returns the wrapped service unchanged.
///
/// Construction ignores state and returns the exact input service without
/// adding a wrapper, readiness cache, or lifecycle behavior. This is useful as
/// a default middleware or a no-op component of a [`Stack`].
;
/// Two middleware values applied in sequence.
///
/// Construction applies `inner` first, then `outer`, with the same state
/// reference: the result is `outer(inner(service))`. Requests enter the outer
/// wrapper first; if forwarded, they then pass through the inner wrapper to
/// the service. Responses return through the inner wrapper before the outer.
///
/// The stack only composes construction. Lifecycle forwarding and whether
/// calls reach the inner service are determined by each wrapper. Cloning
/// clones both middleware values without constructing a service.
///
/// # Example
///
/// ```
/// use ntex_service::{Middleware, Service, Stack, fn_layer, fn_service};
///
/// # async fn example() -> Result<(), ()> {
/// let inner = fn_layer(async |req: u32, ctx| ctx.call(req + 1).await);
/// let outer = fn_layer(async |req: u32, ctx| ctx.call(req * 2).await);
/// let service = Stack::new(inner, outer)
/// .create(&(), fn_service(async |req: u32| Ok::<_, ()>(req)));
///
/// let pipeline = service.pipeline(());
/// assert_eq!(pipeline.call(2).await?, 5);
/// # Ok(())
/// # }
/// ```
/// Creates middleware from an asynchronous function.
///
/// This is the simplest way to write middleware. The function receives an
/// input request and an [`ApplyCtx`] that can call the wrapped service with
/// [`ApplyCtx::call`] or access pipeline state with [`ApplyCtx::st`]. Binding,
/// readiness, and shutdown of the wrapped service are forwarded automatically.
///
/// Each [`Middleware::create`] call clones the function into an [`Apply`]
/// wrapper; it does not invoke it. Request, response, and error types may
/// change, while the state type stays the same. The middleware implementation
/// requires `Err: From<S::Error>` to convert inner readiness errors. See
/// [`crate::apply_fn`] for lifecycle and call-time readiness semantics.
///
/// Annotate the request type, and the response or error type when the
/// closure does not otherwise constrain them.
///
/// # Example
///
/// ```
/// use ntex_service::{Middleware, Service, fn_layer, fn_service};
///
/// # async fn example() -> Result<(), ()> {
/// let log = fn_layer(async |req: u32, ctx| {
/// println!("request: {req}");
/// let res: u32 = ctx.call(req).await?;
/// println!("response: {res}");
/// Ok::<_, ()>(res)
/// });
/// let service = log.create(&(), fn_service(async |req: u32| Ok::<_, ()>(req + 1)));
///
/// assert_eq!(service.pipeline(()).call(1).await?, 2);
/// # Ok(())
/// # }
/// ```
/// Middleware backed by an asynchronous function.
///
/// Created by [`fn_layer`]. Each [`Middleware::create`] call wraps the supplied
/// service in [`Apply`] with a clone of the function. The construction state
/// is not captured automatically; the function accesses current pipeline state
/// through [`ApplyCtx::st`].
///
/// The function controls whether and how often the inner service is called.
/// Binding, readiness, and shutdown follow [`Apply`], including conversion of
/// inner readiness errors through [`From`]. Cloning this middleware clones only
/// the function, not an inner service.