1use crate::io::upgrade::Upgraded;
2
3use super::{UpgradeOutput, UpgradeResponse};
4
5use super::{UpgradeService, service::UpgradeHandler};
6use rama_core::error::BoxError;
7use rama_core::error_sink::{DropErrorSink, ErrorSink, TracingErrorSink};
8use rama_core::{Layer, Service, matcher::Matcher, rt::Executor};
9use rama_http_types::Request;
10use std::{fmt, sync::Arc};
11
12pub struct UpgradeLayer<O> {
18 handlers: Vec<Arc<UpgradeHandler<O>>>,
19 exec: Executor,
20 error_sink: Arc<dyn ErrorSink>,
21}
22
23impl<O: Send + 'static> UpgradeLayer<O> {
24 pub fn new<M, R>(exec: Executor, matcher: M, service: R) -> Self
31 where
32 M: Matcher<Request>,
33 R: Service<Request, Output = UpgradeOutput<Request, O>, Error = O> + Clone,
34 {
35 Self::new_with_error_sink(exec, matcher, service, TracingErrorSink::default())
36 }
37
38 pub fn new_with_error_sink<M, R, Sink>(
40 exec: Executor,
41 matcher: M,
42 service: R,
43 sink: Sink,
44 ) -> Self
45 where
46 M: Matcher<Request>,
47 R: Service<Request, Output = UpgradeOutput<Request, O>, Error = O> + Clone,
48 Sink: ErrorSink,
49 {
50 Self {
51 handlers: vec![Arc::new(UpgradeHandler::new(matcher, service, sink))],
52 exec,
53 error_sink: Arc::new(TracingErrorSink::default()),
54 }
55 }
56
57 pub fn new_dropping_errors<M, R>(exec: Executor, matcher: M, service: R) -> Self
59 where
60 M: Matcher<Request>,
61 R: Service<Request, Output = UpgradeOutput<Request, O>, Error = O> + Clone,
62 {
63 Self::new_with_error_sink(exec, matcher, service, DropErrorSink::new())
64 }
65
66 pub fn new_with_services<M, R, H>(exec: Executor, matcher: M, responder: R, handler: H) -> Self
71 where
72 M: Matcher<Request>,
73 R: Service<Request, Output = UpgradeResponse<Request, O>, Error = O> + Clone,
74 H: Service<Upgraded, Error: Into<BoxError>> + Clone,
75 {
76 Self::new_with_services_and_error_sink(
77 exec,
78 matcher,
79 responder,
80 handler,
81 TracingErrorSink::default(),
82 )
83 }
84
85 pub fn new_with_services_and_error_sink<M, R, H, Sink>(
87 exec: Executor,
88 matcher: M,
89 responder: R,
90 handler: H,
91 sink: Sink,
92 ) -> Self
93 where
94 M: Matcher<Request>,
95 R: Service<Request, Output = UpgradeResponse<Request, O>, Error = O> + Clone,
96 H: Service<Upgraded> + Clone,
97 Sink: ErrorSink<H::Error>,
98 {
99 Self {
100 handlers: vec![Arc::new(UpgradeHandler::new_with_services(
101 matcher, responder, handler, sink,
102 ))],
103 exec,
104 error_sink: Arc::new(TracingErrorSink::default()),
105 }
106 }
107
108 pub fn new_with_services_dropping_errors<M, R, H>(
110 exec: Executor,
111 matcher: M,
112 responder: R,
113 handler: H,
114 ) -> Self
115 where
116 M: Matcher<Request>,
117 R: Service<Request, Output = UpgradeResponse<Request, O>, Error = O> + Clone,
118 H: Service<Upgraded> + Clone,
119 {
120 Self::new_with_services_and_error_sink(
121 exec,
122 matcher,
123 responder,
124 handler,
125 DropErrorSink::new(),
126 )
127 }
128
129 #[must_use]
131 pub fn on<M, R>(self, matcher: M, service: R) -> Self
132 where
133 M: Matcher<Request>,
134 R: Service<Request, Output = UpgradeOutput<Request, O>, Error = O> + Clone,
135 {
136 self.on_with_error_sink(matcher, service, TracingErrorSink::default())
137 }
138
139 #[must_use]
141 pub fn on_with_error_sink<M, R, Sink>(mut self, matcher: M, service: R, sink: Sink) -> Self
142 where
143 M: Matcher<Request>,
144 R: Service<Request, Output = UpgradeOutput<Request, O>, Error = O> + Clone,
145 Sink: ErrorSink,
146 {
147 self.handlers
148 .push(Arc::new(UpgradeHandler::new(matcher, service, sink)));
149 self
150 }
151
152 #[must_use]
154 pub fn on_dropping_errors<M, R>(self, matcher: M, service: R) -> Self
155 where
156 M: Matcher<Request>,
157 R: Service<Request, Output = UpgradeOutput<Request, O>, Error = O> + Clone,
158 {
159 self.on_with_error_sink(matcher, service, DropErrorSink::new())
160 }
161
162 #[must_use]
164 pub fn on_with_services<M, R, H>(self, matcher: M, responder: R, handler: H) -> Self
165 where
166 M: Matcher<Request>,
167 R: Service<Request, Output = UpgradeResponse<Request, O>, Error = O> + Clone,
168 H: Service<Upgraded, Error: Into<BoxError>> + Clone,
169 {
170 self.on_with_services_and_error_sink(
171 matcher,
172 responder,
173 handler,
174 TracingErrorSink::default(),
175 )
176 }
177
178 #[must_use]
180 pub fn on_with_services_and_error_sink<M, R, H, Sink>(
181 mut self,
182 matcher: M,
183 responder: R,
184 handler: H,
185 sink: Sink,
186 ) -> Self
187 where
188 M: Matcher<Request>,
189 R: Service<Request, Output = UpgradeResponse<Request, O>, Error = O> + Clone,
190 H: Service<Upgraded> + Clone,
191 Sink: ErrorSink<H::Error>,
192 {
193 self.handlers
194 .push(Arc::new(UpgradeHandler::new_with_services(
195 matcher, responder, handler, sink,
196 )));
197 self
198 }
199
200 #[must_use]
202 pub fn on_with_services_dropping_errors<M, R, H>(
203 self,
204 matcher: M,
205 responder: R,
206 handler: H,
207 ) -> Self
208 where
209 M: Matcher<Request>,
210 R: Service<Request, Output = UpgradeResponse<Request, O>, Error = O> + Clone,
211 H: Service<Upgraded> + Clone,
212 {
213 self.on_with_services_and_error_sink(matcher, responder, handler, DropErrorSink::new())
214 }
215
216 #[must_use]
224 pub fn with_upgrade_error_sink(mut self, sink: impl ErrorSink) -> Self {
225 self.error_sink = Arc::new(sink);
226 self
227 }
228}
229
230impl<O> fmt::Debug for UpgradeLayer<O> {
231 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
232 f.debug_struct("UpgradeLayer")
233 .field("handlers", &self.handlers)
234 .finish()
235 }
236}
237
238impl<O> Clone for UpgradeLayer<O> {
239 fn clone(&self) -> Self {
240 Self {
241 handlers: self.handlers.clone(),
242 exec: self.exec.clone(),
243 error_sink: self.error_sink.clone(),
244 }
245 }
246}
247
248impl<S, O> Layer<S> for UpgradeLayer<O> {
249 type Service = UpgradeService<S, O>;
250
251 fn layer(&self, inner: S) -> Self::Service {
252 UpgradeService::new(
253 self.handlers.clone(),
254 inner,
255 self.exec.clone(),
256 self.error_sink.clone(),
257 )
258 }
259
260 fn into_layer(self, inner: S) -> Self::Service {
261 UpgradeService::new(self.handlers, inner, self.exec, self.error_sink)
262 }
263}