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
//! Pipeline behaviors: typed (`IPipelineBehavior<Req, Rsp>`) and the legacy
//! type-erased variant (`IErasedPipelineBehavior`).
use crateResult;
use Any;
use Future;
use Pin;
/// Type-erased continuation function used by [`IErasedPipelineBehavior`].
pub type BoxedNextFn = ;
/// Boxed future returned by a type-erased pipeline step.
pub type BoxedPipelineFuture = ;
/// The continuation a typed behavior calls to run the rest of the chain.
///
/// The framework builds this value; behaviors only consume it:
///
/// ```ignore
/// let response = next.run(req).await?; // run the remaining chain + handler
/// ```
/// Boxed future returned by one typed pipeline step.
type NextFuture<Rsp> = ;
/// Callable continuation stored by [`Next`].
type NextCall<Req, Rsp> = ;
/// Typed pipeline behavior that wraps around request handling.
///
/// Multiple behaviors form a chain: the first registered behavior is the
/// outermost (runs first on the request, last on the response). A behavior can
/// inspect/modify the request and response, or **short-circuit** by returning a
/// response without calling [`Next::run`] — the value is the handler's response
/// type, checked by the compiler:
///
/// ```ignore
/// #[derive(Default)]
/// struct RequireNotes;
///
/// #[async_trait::async_trait]
/// impl IPipelineBehavior<CreateOrderRequest, OrderView> for RequireNotes {
/// async fn handle(
/// &self,
/// req: CreateOrderRequest,
/// next: Next<CreateOrderRequest, OrderView>,
/// ) -> Result<OrderView> {
/// if req.note.is_empty() {
/// return Err(Error::Validation("note is required".into()));
/// }
/// next.run(req).await
/// }
/// }
///
/// svc.add_typed_pipeline::<RequireNotes, CreateOrderRequest, OrderView>();
/// ```
///
/// Behaviors are **singletons** (one instance per host). The DI resolver is only
/// available while a behavior is being **constructed**:
/// [`IServiceCollectionExt::add_typed_pipeline_with`] hands the factory the
/// resolver; inside `handle` only the typed request/continuation exist.
///
/// [`IServiceCollectionExt::add_typed_pipeline_with`]:
/// crate::route::ext::IServiceCollectionExt::add_typed_pipeline_with
/// Legacy type-erased pipeline behavior (deprecated since 0.10.0).
///
/// Kept for one release so existing behaviors keep compiling and running: the
/// erased chain runs **outside** the typed chain, so it observes the request
/// before typed behaviors and the response after them. A short-circuit here
/// must still return the handler's response type as `Box<dyn Any + Send>`;
/// prefer [`IPipelineBehavior`] for new code.