1use crate::io::upgrade::Upgraded;
2
3use super::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> UpgradeLayer<O> {
24 pub fn new<M, R, H>(exec: Executor, matcher: M, responder: R, handler: H) -> Self
31 where
32 M: Matcher<Request>,
33 R: Service<Request, Output = UpgradeResponse<Request, O>, Error = O> + Clone,
34 H: Service<Upgraded, Output = (), Error: Into<BoxError>> + Clone,
35 {
36 Self::new_with_error_sink(
37 exec,
38 matcher,
39 responder,
40 handler,
41 TracingErrorSink::default(),
42 )
43 }
44
45 pub fn new_with_error_sink<M, R, H, Sink>(
48 exec: Executor,
49 matcher: M,
50 responder: R,
51 handler: H,
52 sink: Sink,
53 ) -> Self
54 where
55 M: Matcher<Request>,
56 R: Service<Request, Output = UpgradeResponse<Request, O>, Error = O> + Clone,
57 H: Service<Upgraded, Output = ()> + Clone,
58 Sink: ErrorSink<H::Error>,
59 {
60 Self {
61 handlers: vec![Arc::new(UpgradeHandler::new(
62 matcher, responder, handler, sink,
63 ))],
64 exec,
65 error_sink: Arc::new(TracingErrorSink::default()),
66 }
67 }
68
69 pub fn new_dropping_errors<M, R, H>(
73 exec: Executor,
74 matcher: M,
75 responder: R,
76 handler: H,
77 ) -> Self
78 where
79 M: Matcher<Request>,
80 R: Service<Request, Output = UpgradeResponse<Request, O>, Error = O> + Clone,
81 H: Service<Upgraded, Output = ()> + Clone,
82 {
83 Self::new_with_error_sink(exec, matcher, responder, handler, DropErrorSink::new())
84 }
85
86 #[must_use]
89 pub fn on<M, R, H>(self, matcher: M, responder: R, handler: H) -> Self
90 where
91 M: Matcher<Request>,
92 R: Service<Request, Output = UpgradeResponse<Request, O>, Error = O> + Clone,
93 H: Service<Upgraded, Output = (), Error: Into<BoxError>> + Clone,
94 {
95 self.on_with_error_sink(matcher, responder, handler, TracingErrorSink::default())
96 }
97
98 #[must_use]
101 pub fn on_dropping_errors<M, R, H>(self, matcher: M, responder: R, handler: H) -> Self
102 where
103 M: Matcher<Request>,
104 R: Service<Request, Output = UpgradeResponse<Request, O>, Error = O> + Clone,
105 H: Service<Upgraded, Output = ()> + Clone,
106 {
107 self.on_with_error_sink(matcher, responder, handler, DropErrorSink::new())
108 }
109
110 #[must_use]
113 pub fn on_with_error_sink<M, R, H, Sink>(
114 mut self,
115 matcher: M,
116 responder: R,
117 handler: H,
118 sink: Sink,
119 ) -> Self
120 where
121 M: Matcher<Request>,
122 R: Service<Request, Output = UpgradeResponse<Request, O>, Error = O> + Clone,
123 H: Service<Upgraded, Output = ()> + Clone,
124 Sink: ErrorSink<H::Error>,
125 {
126 self.handlers.push(Arc::new(UpgradeHandler::new(
127 matcher, responder, handler, sink,
128 )));
129 self
130 }
131
132 #[must_use]
139 pub fn with_upgrade_error_sink(mut self, sink: impl ErrorSink) -> Self {
140 self.error_sink = Arc::new(sink);
141 self
142 }
143}
144
145impl<O> fmt::Debug for UpgradeLayer<O> {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 f.debug_struct("UpgradeLayer")
148 .field("handlers", &self.handlers)
149 .finish()
150 }
151}
152
153impl<O> Clone for UpgradeLayer<O> {
154 fn clone(&self) -> Self {
155 Self {
156 handlers: self.handlers.clone(),
157 exec: self.exec.clone(),
158 error_sink: self.error_sink.clone(),
159 }
160 }
161}
162
163impl<S, O> Layer<S> for UpgradeLayer<O> {
164 type Service = UpgradeService<S, O>;
165
166 fn layer(&self, inner: S) -> Self::Service {
167 UpgradeService::new(
168 self.handlers.clone(),
169 inner,
170 self.exec.clone(),
171 self.error_sink.clone(),
172 )
173 }
174
175 fn into_layer(self, inner: S) -> Self::Service {
176 UpgradeService::new(self.handlers, inner, self.exec, self.error_sink)
177 }
178}