1use crate::{Context, Layer, Service, context::Extensions, matcher::Matcher};
11use rama_utils::macros::define_inner_service_accessors;
12
13pub struct HijackService<S, H, M> {
22 inner: S,
23 hijack: H,
24 matcher: M,
25}
26
27impl<S, H, M> std::fmt::Debug for HijackService<S, H, M> {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 f.debug_struct("HijackService").finish()
30 }
31}
32
33impl<S, H, M> Clone for HijackService<S, H, M>
34where
35 S: Clone,
36 H: Clone,
37 M: Clone,
38{
39 fn clone(&self) -> Self {
40 Self {
41 inner: self.inner.clone(),
42 hijack: self.hijack.clone(),
43 matcher: self.matcher.clone(),
44 }
45 }
46}
47
48impl<S, H, M> HijackService<S, H, M> {
49 pub const fn new(inner: S, hijack: H, matcher: M) -> Self {
51 Self {
52 inner,
53 hijack,
54 matcher,
55 }
56 }
57
58 define_inner_service_accessors!();
59}
60
61impl<S, H, M, State, Request> Service<State, Request> for HijackService<S, H, M>
62where
63 S: Service<State, Request>,
64 H: Service<State, Request, Response: Into<S::Response>, Error: Into<S::Error>>,
65 M: Matcher<State, Request>,
66 State: Clone + Send + Sync + 'static,
67 Request: Send + 'static,
68{
69 type Response = S::Response;
70 type Error = S::Error;
71
72 async fn serve(
73 &self,
74 mut ctx: Context<State>,
75 req: Request,
76 ) -> Result<Self::Response, Self::Error> {
77 let mut ext = Extensions::new();
78 if self.matcher.matches(Some(&mut ext), &ctx, &req) {
79 ctx.extend(ext);
80 match self.hijack.serve(ctx, req).await {
81 Ok(response) => Ok(response.into()),
82 Err(err) => Err(err.into()),
83 }
84 } else {
85 self.inner.serve(ctx, req).await
86 }
87 }
88}
89
90pub struct HijackLayer<H, M> {
99 hijack: H,
100 matcher: M,
101}
102
103impl<H, M> std::fmt::Debug for HijackLayer<H, M> {
104 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105 f.debug_struct("HijackLayer").finish()
106 }
107}
108
109impl<H, M> Clone for HijackLayer<H, M>
110where
111 H: Clone,
112 M: Clone,
113{
114 fn clone(&self) -> Self {
115 Self {
116 hijack: self.hijack.clone(),
117 matcher: self.matcher.clone(),
118 }
119 }
120}
121
122impl<H, M> HijackLayer<H, M> {
123 pub const fn new(matcher: M, hijack: H) -> Self {
125 Self { hijack, matcher }
126 }
127}
128
129impl<S, H, M> Layer<S> for HijackLayer<H, M>
130where
131 H: Clone,
132 M: Clone,
133{
134 type Service = HijackService<S, H, M>;
135
136 fn layer(&self, inner: S) -> Self::Service {
137 HijackService::new(inner, self.hijack.clone(), self.matcher.clone())
138 }
139
140 fn into_layer(self, inner: S) -> Self::Service {
141 HijackService::new(inner, self.hijack, self.matcher)
142 }
143}