1use super::handler::Handler;
2use std::marker::PhantomData;
3
4pub trait Middleware<In, E: Handler<In>> {
5 type Output: Handler<In>;
6 fn transform(self, handler: E) -> Self::Output;
7 fn chain<Out, M2, E3>(self, other: M2) -> JoinMiddleware<In, Out, Self::Output, Self, E, M2, E3>
8 where
9 Self: Sized + 'static,
10 Self::Output: Handler<In, Out = Out>,
11 In: Send + Sync + 'static,
12 Out: Send + Sync + 'static,
13 E: Handler<In, Out = Out>,
14 M2: Middleware<In, E3, Output = E> + 'static,
15 E3: Handler<In, Out = Out>,
16 {
17 JoinMiddleware::new(self, other)
18 }
19}
20
21pub struct JoinMiddleware<In, Out, E1, M1, E2, M2, E3>
22where
23 In: Send + Sync + 'static,
24 Out: Send + Sync + 'static,
25 E1: Handler<In, Out = Out>,
26 M1: Middleware<In, E2, Output = E1>,
27 E2: Handler<In, Out = Out>,
28 M2: Middleware<In, E3, Output = E2>,
29 E3: Handler<In, Out = Out>,
30{
31 middleware1: M1,
32 middleware2: M2,
33 phantom1: PhantomData<In>,
34 phantom2: PhantomData<Out>,
35 phantom3: PhantomData<E1>,
36 phantom4: PhantomData<E2>,
37 phantom5: PhantomData<E3>,
38}
39
40impl<In, Out, E1, M1, E2, M2, E3> Middleware<In, E3> for JoinMiddleware<In, Out, E1, M1, E2, M2, E3>
41where
42 In: Send + Sync + 'static,
43 Out: Send + Sync + 'static,
44 E1: Handler<In, Out = Out>,
45 M1: Middleware<In, E2, Output = E1>,
46 E2: Handler<In, Out = Out>,
47 M2: Middleware<In, E3, Output = E2>,
48 E3: Handler<In, Out = Out>,
49{
50 type Output = E1;
51
52 fn transform(self, handler: E3) -> Self::Output {
53 self.middleware1
54 .transform(self.middleware2.transform(handler))
55 }
56}
57
58impl<In, Out, E1, M1, E2, M2, E3> JoinMiddleware<In, Out, E1, M1, E2, M2, E3>
59where
60 In: Send + Sync + 'static,
61 Out: Send + Sync + 'static,
62 E1: Handler<In, Out = Out>,
63 M1: Middleware<In, E2, Output = E1>,
64 E2: Handler<In, Out = Out>,
65 M2: Middleware<In, E3, Output = E2>,
66 E3: Handler<In, Out = Out>,
67{
68 pub fn new(middleware1: M1, middleware2: M2) -> JoinMiddleware<In, Out, E1, M1, E2, M2, E3> {
69 JoinMiddleware {
70 middleware1: middleware1,
71 middleware2: middleware2,
72 phantom1: PhantomData,
73 phantom2: PhantomData,
74 phantom3: PhantomData,
75 phantom4: PhantomData,
76 phantom5: PhantomData,
77 }
78 }
79}