spire_core/worker/middleware/
mod.rs1mod header;
40mod revalidate;
41
42use std::fmt;
43use std::future::Future;
44use std::sync::Arc;
45
46use futures::future::BoxFuture;
47pub use header::SetHeader;
48pub use revalidate::{InMemValidators, Revalidate, Validator, Validators};
49
50use crate::context::Context;
51use crate::worker::{IntoOutcome, Outcome, Worker};
52
53pub trait Middleware<C>: Send + Sync + 'static {
55 fn handle(&self, cx: Context<C>, next: Next<C>) -> impl Future<Output = Outcome> + Send;
57}
58
59pub struct Next<C> {
62 worker: Arc<dyn ErasedWorker<C>>,
63}
64
65impl<C> Next<C> {
66 pub async fn run(self, cx: Context<C>) -> Outcome
68 where
69 C: Send + 'static,
70 {
71 self.worker.handle(cx).await
72 }
73}
74
75impl<C> fmt::Debug for Next<C> {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 f.debug_struct("Next").finish_non_exhaustive()
78 }
79}
80
81trait ErasedWorker<C>: Send + Sync + 'static {
83 fn handle(&self, cx: Context<C>) -> BoxFuture<'_, Outcome>;
84}
85
86impl<C: Send + 'static, W: Worker<C>> ErasedWorker<C> for W {
87 fn handle(&self, cx: Context<C>) -> BoxFuture<'_, Outcome> {
88 Box::pin(Worker::handle(self, cx))
89 }
90}
91
92pub trait WorkerExt: Sized {
94 fn layer<C, M>(self, middleware: M) -> Layered<M, C>
97 where
98 C: Send + 'static,
99 Self: Worker<C>,
100 M: Middleware<C>,
101 {
102 Layered {
103 middleware,
104 worker: Arc::new(self),
105 }
106 }
107}
108
109impl<W> WorkerExt for W {}
110
111pub struct Layered<M, C> {
113 middleware: M,
114 worker: Arc<dyn ErasedWorker<C>>,
115}
116
117impl<M, C> Worker<C> for Layered<M, C>
118where
119 M: Middleware<C>,
120 C: Send + 'static,
121{
122 fn handle(&self, cx: Context<C>) -> impl Future<Output = Outcome> + Send {
123 let next = Next {
124 worker: Arc::clone(&self.worker),
125 };
126 self.middleware.handle(cx, next)
127 }
128}
129
130impl<M: Clone, C> Clone for Layered<M, C> {
131 fn clone(&self) -> Self {
132 Self {
133 middleware: self.middleware.clone(),
134 worker: Arc::clone(&self.worker),
135 }
136 }
137}
138
139impl<M: fmt::Debug, C> fmt::Debug for Layered<M, C> {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 f.debug_struct("Layered")
142 .field("middleware", &self.middleware)
143 .finish_non_exhaustive()
144 }
145}
146
147pub const fn from_fn<F>(f: F) -> FromFn<F> {
151 FromFn(f)
152}
153
154#[derive(Clone, Copy)]
156pub struct FromFn<F>(F);
157
158impl<C, F, Fut> Middleware<C> for FromFn<F>
159where
160 C: Send + 'static,
161 F: Fn(Context<C>, Next<C>) -> Fut + Send + Sync + 'static,
162 Fut: Future<Output: IntoOutcome> + Send,
163{
164 fn handle(&self, cx: Context<C>, next: Next<C>) -> impl Future<Output = Outcome> + Send {
165 let future = (self.0)(cx, next);
166 async move { future.await.into_outcome() }
167 }
168}
169
170impl<F> fmt::Debug for FromFn<F> {
171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 f.debug_struct("FromFn").finish_non_exhaustive()
173 }
174}
175
176#[cfg(test)]
177mod tests;