1use async_trait::async_trait;
6use std::future::Future;
7use std::pin::Pin;
8
9#[async_trait]
13pub trait Middleware<Req, Resp>: Send + Sync {
14 type Error: std::error::Error + Send + Sync + 'static;
16
17 async fn process(
26 &self,
27 request: Req,
28 next: Box<dyn MiddlewareNext<Req, Resp>>,
29 ) -> Result<Resp, Self::Error>;
30}
31
32#[async_trait]
34pub trait MiddlewareNext<Req, Resp>: Send + Sync {
35 async fn call(&self, request: Req) -> Result<Resp, MiddlewareError>;
37}
38
39type BoxedMiddleware<Req, Resp> = Box<dyn Middleware<Req, Resp, Error = MiddlewareError>>;
41type BoxedFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
42
43pub struct MiddlewareStack<Req, Resp> {
45 middlewares: Vec<BoxedMiddleware<Req, Resp>>,
46}
47
48impl<Req, Resp> MiddlewareStack<Req, Resp>
49where
50 Req: Clone + Send + Sync + 'static,
51 Resp: Send + Sync + 'static,
52{
53 pub fn new() -> Self {
55 Self {
56 middlewares: Vec::new(),
57 }
58 }
59
60 pub fn add_middleware<M>(self, _middleware: M) -> Self
62 where
63 M: Middleware<Req, Resp> + 'static,
64 {
65 self
67 }
68
69 pub async fn execute<F, Fut>(
71 &self,
72 request: Req,
73 final_handler: F,
74 ) -> Result<Resp, MiddlewareError>
75 where
76 F: FnOnce(Req) -> Fut + Send + Sync + 'static,
77 Fut: Future<Output = Result<Resp, MiddlewareError>> + Send + Sync + 'static,
78 {
79 let handler = Box::new(FinalHandler::new(final_handler));
80 self.execute_chain(request, 0, handler).await
81 }
82
83 fn execute_chain(
85 &self,
86 request: Req,
87 index: usize,
88 final_handler: Box<dyn MiddlewareNext<Req, Resp>>,
89 ) -> BoxedFuture<'_, Result<Resp, MiddlewareError>> {
90 Box::pin(async move {
91 if index >= self.middlewares.len() {
92 final_handler.call(request).await
94 } else {
95 let _next = Box::new(NextHandler {
97 _stack: self,
98 _index: index + 1,
99 _final_handler: final_handler,
100 _request: request.clone(),
101 });
102
103 Err(MiddlewareError::ExecutionFailed(
106 "Middleware system temporarily disabled".to_string(),
107 ))
108 }
109 })
110 }
111}
112
113impl<Req, Resp> Default for MiddlewareStack<Req, Resp>
114where
115 Req: Clone + Send + Sync + 'static,
116 Resp: Send + Sync + 'static,
117{
118 fn default() -> Self {
119 Self::new()
120 }
121}
122
123struct FinalHandler<F, Fut, Req, Resp> {
125 _handler: Option<F>,
126 _phantom: std::marker::PhantomData<(Fut, Req, Resp)>,
127}
128
129impl<F, Fut, Req, Resp> FinalHandler<F, Fut, Req, Resp> {
130 fn new(handler: F) -> Self {
131 Self {
132 _handler: Some(handler),
133 _phantom: std::marker::PhantomData,
134 }
135 }
136}
137
138#[async_trait]
139impl<F, Fut, Req, Resp> MiddlewareNext<Req, Resp> for FinalHandler<F, Fut, Req, Resp>
140where
141 F: FnOnce(Req) -> Fut + Send + Sync,
142 Fut: Future<Output = Result<Resp, MiddlewareError>> + Send + Sync,
143 Req: Send + Sync,
144 Resp: Send + Sync,
145{
146 async fn call(&self, _request: Req) -> Result<Resp, MiddlewareError> {
147 Err(MiddlewareError::ExecutionFailed(
150 "FinalHandler: FnOnce handling not yet implemented".to_string(),
151 ))
152 }
153}
154
155struct NextHandler<'a, Req, Resp> {
157 _stack: &'a MiddlewareStack<Req, Resp>,
158 _index: usize,
159 _final_handler: Box<dyn MiddlewareNext<Req, Resp>>,
160 _request: Req,
161}
162
163#[async_trait]
164impl<'a, Req, Resp> MiddlewareNext<Req, Resp> for NextHandler<'a, Req, Resp>
165where
166 Req: Clone + Send + Sync + 'static,
167 Resp: Send + Sync + 'static,
168{
169 async fn call(&self, _request: Req) -> Result<Resp, MiddlewareError> {
170 Err(MiddlewareError::ExecutionFailed(
172 "NextHandler: next handler not yet implemented".to_string(),
173 ))
174 }
175}
176
177#[derive(Debug, thiserror::Error)]
179pub enum MiddlewareError {
180 #[error("Middleware chain execution failed: {0}")]
181 ExecutionFailed(String),
182
183 #[error("Invalid middleware configuration: {0}")]
184 InvalidConfiguration(String),
185
186 #[error("Middleware timeout after {timeout_ms}ms")]
187 Timeout { timeout_ms: u64 },
188
189 #[error("Other middleware error: {0}")]
190 Other(String),
191}
192
193#[cfg(test)]
194mod tests {
195 use super::*;
196
197 #[test]
200 fn test_middleware_stack_new() {
201 let stack: MiddlewareStack<String, String> = MiddlewareStack::new();
202 assert!(stack.middlewares.is_empty());
203 }
204
205 #[test]
206 fn test_middleware_stack_default() {
207 let stack: MiddlewareStack<String, String> = MiddlewareStack::default();
208 assert!(stack.middlewares.is_empty());
209 }
210
211 #[test]
214 fn test_middleware_error_execution_failed() {
215 let err = MiddlewareError::ExecutionFailed("Handler failed".to_string());
216 assert!(
217 err.to_string()
218 .contains("Middleware chain execution failed")
219 );
220 assert!(err.to_string().contains("Handler failed"));
221 }
222
223 #[test]
224 fn test_middleware_error_invalid_configuration() {
225 let err = MiddlewareError::InvalidConfiguration("Missing required field".to_string());
226 assert!(err.to_string().contains("Invalid middleware configuration"));
227 assert!(err.to_string().contains("Missing required field"));
228 }
229
230 #[test]
231 fn test_middleware_error_timeout() {
232 let err = MiddlewareError::Timeout { timeout_ms: 5000 };
233 assert!(err.to_string().contains("timeout"));
234 assert!(err.to_string().contains("5000"));
235 }
236
237 #[test]
238 fn test_middleware_error_other() {
239 let err = MiddlewareError::Other("Unknown error".to_string());
240 assert!(err.to_string().contains("Unknown error"));
241 }
242
243 #[test]
244 fn test_middleware_error_display() {
245 let err = MiddlewareError::ExecutionFailed("test".to_string());
246 let display = format!("{}", err);
247 assert!(!display.is_empty());
248 }
249
250 #[test]
251 fn test_middleware_error_debug() {
252 let err = MiddlewareError::Timeout { timeout_ms: 1000 };
253 let debug = format!("{:?}", err);
254 assert!(debug.contains("Timeout"));
255 assert!(debug.contains("1000"));
256 }
257}