rama_core/matcher/service/
tuples.rs1use rama_error::{BoxError, ErrorContext};
2
3use crate::extensions::ExtensionsRef;
4
5use super::{ServiceMatch, ServiceMatcher};
6
7macro_rules! impl_service_matcher_tuple {
8 ($either:ident, $first_variant:ident => $first_ty:ident : $first_var:ident, $($variant:ident => $rest_ty:ident : $rest_var:ident),+ $(,)?) => {
9 impl<Input, ModifiedInput, $first_ty, $($rest_ty),+> ServiceMatcher<Input>
10 for ($first_ty, $($rest_ty),+)
11 where
12 Input: Send + ExtensionsRef + 'static,
13 ModifiedInput: Send + 'static,
14 $first_ty: ServiceMatcher<Input, Error: Into<BoxError>, ModifiedInput = ModifiedInput>,
15 $(
16 $rest_ty: ServiceMatcher<
17 ModifiedInput,
18 Error: Into<BoxError>,
19 ModifiedInput = ModifiedInput,
20 >,
21 )+
22 {
23 type Service = crate::combinators::$either<$first_ty::Service, $($rest_ty::Service),+>;
24 type Error = BoxError;
25 type ModifiedInput = ModifiedInput;
26
27 async fn match_service(
28 &self,
29 input: Input,
30 ) -> Result<ServiceMatch<Self::ModifiedInput, Self::Service>, Self::Error> {
31 let ($first_var, $($rest_var),+) = self;
32
33 let ServiceMatch { input, service } = $first_var.match_service(input).await.into_box_error()?;
34 if let Some(service) = service {
35 return Ok(ServiceMatch {
36 input,
37 service: Some(crate::combinators::$either::$first_variant(service)),
38 });
39 }
40
41 $(
42 let ServiceMatch { input, service } = $rest_var.match_service(input).await.into_box_error()?;
43 if let Some(service) = service {
44 return Ok(ServiceMatch {
45 input,
46 service: Some(crate::combinators::$either::$variant(service)),
47 });
48 }
49 )+
50
51 Ok(ServiceMatch {
52 input,
53 service: None,
54 })
55 }
56
57 async fn into_match_service(
58 self,
59 input: Input,
60 ) -> Result<ServiceMatch<Self::ModifiedInput, Self::Service>, Self::Error>
61 where
62 Input: Send,
63 {
64 let ($first_var, $($rest_var),+) = self;
65
66 let ServiceMatch { input, service } = $first_var.into_match_service(input).await.into_box_error()?;
67 if let Some(service) = service {
68 return Ok(ServiceMatch {
69 input,
70 service: Some(crate::combinators::$either::$first_variant(service)),
71 });
72 }
73
74 $(
75 let ServiceMatch { input, service } = $rest_var.into_match_service(input).await.into_box_error()?;
76 if let Some(service) = service {
77 return Ok(ServiceMatch {
78 input,
79 service: Some(crate::combinators::$either::$variant(service)),
80 });
81 }
82 )+
83
84 Ok(ServiceMatch {
85 input,
86 service: None,
87 })
88 }
89 }
90 };
91}
92
93impl_service_matcher_tuple!(Either, A => SM1: sm1, B => SM2: sm2);
94impl_service_matcher_tuple!(Either3, A => SM1: sm1, B => SM2: sm2, C => SM3: sm3);
95impl_service_matcher_tuple!(Either4, A => SM1: sm1, B => SM2: sm2, C => SM3: sm3, D => SM4: sm4);
96impl_service_matcher_tuple!(Either5, A => SM1: sm1, B => SM2: sm2, C => SM3: sm3, D => SM4: sm4, E => SM5: sm5);
97impl_service_matcher_tuple!(Either6, A => SM1: sm1, B => SM2: sm2, C => SM3: sm3, D => SM4: sm4, E => SM5: sm5, F => SM6: sm6);
98impl_service_matcher_tuple!(Either7, A => SM1: sm1, B => SM2: sm2, C => SM3: sm3, D => SM4: sm4, E => SM5: sm5, F => SM6: sm6, G => SM7: sm7);
99impl_service_matcher_tuple!(Either8, A => SM1: sm1, B => SM2: sm2, C => SM3: sm3, D => SM4: sm4, E => SM5: sm5, F => SM6: sm6, G => SM7: sm7, H => SM8: sm8);
100impl_service_matcher_tuple!(Either9, A => SM1: sm1, B => SM2: sm2, C => SM3: sm3, D => SM4: sm4, E => SM5: sm5, F => SM6: sm6, G => SM7: sm7, H => SM8: sm8, I => SM9: sm9);
101
102macro_rules! impl_service_matcher_either {
103 ($either:ident, $first:ident $(, $rest:ident)* $(,)?) => {
104 impl<Input, ModifiedInput, $first, $($rest,)*> ServiceMatcher<Input>
105 for crate::combinators::$either<$first $(, $rest)*>
106 where
107 Input: Send + 'static,
108 ModifiedInput: Send + 'static,
109 $first: ServiceMatcher<Input, ModifiedInput = ModifiedInput>,
110 $(
111 $rest: ServiceMatcher<
112 Input,
113 ModifiedInput = ModifiedInput,
114 Error: Into<$first::Error>,
115 >,
116 )*
117 {
118 type Service = crate::combinators::$either<$first::Service $(, $rest::Service)*>;
119 type Error = $first::Error;
120 type ModifiedInput = ModifiedInput;
121
122 async fn match_service(
123 &self,
124 input: Input,
125 ) -> Result<ServiceMatch<Self::ModifiedInput, Self::Service>, Self::Error> {
126 match self {
127 crate::combinators::$either::$first(matcher) => {
128 matcher.match_service(input).await.map(|sm| ServiceMatch {
129 input: sm.input,
130 service: sm.service.map(crate::combinators::$either::$first),
131 })
132 }
133 $(
134 crate::combinators::$either::$rest(matcher) => {
135 matcher.match_service(input).await.map_err(Into::into).map(|sm| ServiceMatch {
136 input: sm.input,
137 service: sm.service.map(crate::combinators::$either::$rest),
138 })
139 }
140 )*
141 }
142 }
143
144 async fn into_match_service(
145 self,
146 input: Input,
147 ) -> Result<ServiceMatch<Self::ModifiedInput, Self::Service>, Self::Error>
148 where
149 Input: Send,
150 {
151 match self {
152 crate::combinators::$either::$first(matcher) => {
153 matcher.into_match_service(input).await.map(|sm| ServiceMatch {
154 input: sm.input,
155 service: sm.service.map(crate::combinators::$either::$first),
156 })
157 }
158 $(
159 crate::combinators::$either::$rest(matcher) => {
160 matcher.into_match_service(input).await.map_err(Into::into).map(|sm| ServiceMatch {
161 input: sm.input,
162 service: sm.service.map(crate::combinators::$either::$rest),
163 })
164 }
165 )*
166 }
167 }
168 }
169 };
170}
171
172crate::combinators::impl_either!(impl_service_matcher_either);