1use std::{fmt::Debug, future::Future, pin::Pin};
2
3use crate::{
4 context::{Context, DefaultContext},
5 error::{DefaultError, Error},
6};
7
8pub type NextHandler<TContext, TErrorData> = Box<
9 dyn Fn(
10 TContext,
11 ) -> Pin<
12 Box<
13 dyn Future<Output = Result<TContext, Error<TErrorData>>> + Send,
14 >,
15 > + Send
16 + Sync,
17>;
18
19#[async_trait::async_trait]
20pub trait Middleware<TContext, TErrorData>
21where
22 TContext: Context + Debug + Send + Sync,
23 TErrorData: Default + Send + Sync,
24{
25 async fn run_middleware(
26 &self,
27 context: TContext,
28 next: NextHandler<TContext, TErrorData>,
29 ) -> Result<TContext, Error<TErrorData>>;
30}
31
32type DefaultMiddlewareHandler = fn(
33 DefaultContext,
34 NextHandler<DefaultContext, ()>,
35) -> Pin<
36 Box<dyn Future<Output = Result<DefaultContext, DefaultError>> + Send>,
37>;
38
39#[derive(Clone)]
40pub struct DefaultMiddleware<TData>
41where
42 TData: Default + Clone + Send + Sync,
43{
44 handler: DefaultMiddlewareHandler,
45 #[allow(dead_code)]
46 data: TData,
47}
48
49impl<TData> DefaultMiddleware<TData>
50where
51 TData: Default + Clone + Send + Sync,
52{
53 pub fn new(handler: DefaultMiddlewareHandler) -> Self {
54 DefaultMiddleware {
55 handler,
56 data: Default::default(),
57 }
58 }
59
60 pub fn new_with_data(
61 handler: DefaultMiddlewareHandler,
62 data: TData,
63 ) -> Self {
64 DefaultMiddleware { handler, data }
65 }
66}
67
68#[async_trait::async_trait]
69impl<TData> Middleware<DefaultContext, ()> for DefaultMiddleware<TData>
70where
71 TData: Default + Clone + Send + Sync,
72{
73 async fn run_middleware(
74 &self,
75 context: DefaultContext,
76 next: NextHandler<DefaultContext, ()>,
77 ) -> Result<DefaultContext, DefaultError> {
78 (self.handler)(context, next).await
79 }
80}