1use http::Response;
4use http_body::Body;
5use pin_project_lite::pin_project;
6use std::{
7 future::Future,
8 pin::Pin,
9 task::{Context, Poll},
10};
11use tower::{util::Oneshot, ServiceExt};
12use tower_service::Service;
13
14#[allow(missing_docs)]
18pub trait SendService<Request>: send_service::Sealed<Request> {
19 type Service: Service<
20 Request,
21 Response = Response<Self::Body>,
22 Error = Self::Error,
23 Future = Self::Future,
24 > + Send
25 + Clone
26 + 'static;
27
28 type Body: Body<Data = Self::BodyData, Error = Self::BodyError> + Send + 'static;
29 type BodyData: Send + 'static;
30 type BodyError: Into<Box<dyn std::error::Error + Send + Sync>>;
31
32 type Error: Into<Box<dyn std::error::Error + Send + Sync>>;
33
34 type Future: Future<Output = Result<Response<Self::Body>, Self::Error>> + Send + 'static;
35
36 fn into_service(self) -> Self::Service;
37}
38
39impl<T, B, Request> send_service::Sealed<Request> for T
40where
41 T: Service<Request, Response = Response<B>>,
42 T::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
43 T::Future: Send + 'static,
44 B: Body + Send + 'static,
45 B::Data: Send + 'static,
46 B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
47{
48}
49
50impl<T, B, Request> SendService<Request> for T
51where
52 T: Service<Request, Response = Response<B>> + Send + Clone + 'static,
53 T::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
54 T::Future: Send + 'static,
55 B: Body + Send + 'static,
56 B::Data: Send + 'static,
57 B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
58{
59 type Service = T;
60
61 type Body = B;
62 type BodyData = B::Data;
63 type BodyError = B::Error;
64
65 type Error = T::Error;
66
67 type Future = T::Future;
68
69 fn into_service(self) -> Self::Service {
70 self
71 }
72}
73
74#[allow(missing_docs)]
81pub trait MakeService<Target, Request>: make_service_ref::Sealed<(Target, Request)> {
82 type Service: Service<
83 Request,
84 Response = Response<Self::Body>,
85 Error = Self::Error,
86 Future = Self::Future,
87 >
88 + Send
89 + 'static
90 + Clone;
91
92 type Body: Body<Data = Self::BodyData, Error = Self::BodyError> + Send + 'static;
93 type BodyData: Send + 'static;
94 type BodyError: Into<Box<dyn std::error::Error + Send + Sync>>;
95
96 type Error: Into<Box<dyn std::error::Error + Send + Sync>>;
97
98 type Future: Future<Output = Result<Response<Self::Body>, Self::Error>> + Send + 'static;
99
100 type MakeError: Into<Box<dyn std::error::Error + Send + Sync>>;
101 type MakeFuture: Future<Output = Result<Self::Service, Self::MakeError>>;
102
103 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::MakeError>>;
104
105 fn make_service(&mut self, target: Target) -> Self::MakeFuture;
106}
107
108impl<T, S, B, E, F, Target, Request> make_service_ref::Sealed<(Target, Request)> for T
109where
110 T: Service<Target, Response = S, Error = E, Future = F>,
111 S: Service<Request, Response = Response<B>> + Send + 'static,
112 S::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
113 S::Future: Send + 'static,
114 B: Body + Send + 'static,
115 B::Data: Send + 'static,
116 B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
117 E: Into<Box<dyn std::error::Error + Send + Sync>>,
118 F: Future<Output = Result<S, E>>,
119{
120}
121
122impl<T, S, B, E, F, Target, Request> MakeService<Target, Request> for T
123where
124 T: Service<Target, Response = S, Error = E, Future = F>,
125 S: Service<Request, Response = Response<B>> + Send + Clone + 'static,
126 S::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
127 S::Future: Send + 'static,
128 B: Body + Send + 'static,
129 B::Data: Send + 'static,
130 B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
131 E: Into<Box<dyn std::error::Error + Send + Sync>>,
132 F: Future<Output = Result<S, E>>,
133{
134 type Service = S;
135
136 type Body = B;
137 type BodyData = B::Data;
138 type BodyError = B::Error;
139
140 type Error = S::Error;
141
142 type Future = S::Future;
143
144 type MakeError = E;
145 type MakeFuture = F;
146
147 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::MakeError>> {
148 self.poll_ready(cx)
149 }
150
151 fn make_service(&mut self, target: Target) -> Self::MakeFuture {
152 self.call(target)
153 }
154}
155
156mod send_service {
157 pub trait Sealed<T> {}
158}
159
160mod make_service_ref {
161 pub trait Sealed<T> {}
162}
163
164#[derive(Debug, Copy, Clone)]
166pub(crate) struct TowerToHyperService<S> {
167 service: S,
168}
169
170impl<S> TowerToHyperService<S> {
171 pub(crate) fn new(tower_service: S) -> Self {
173 Self {
174 service: tower_service,
175 }
176 }
177}
178
179impl<S, R> hyper::service::Service<R> for TowerToHyperService<S>
180where
181 S: tower_service::Service<R> + Clone,
182{
183 type Response = S::Response;
184 type Error = S::Error;
185 type Future = TowerToHyperServiceFuture<S, R>;
186
187 fn call(&self, req: R) -> Self::Future {
188 TowerToHyperServiceFuture {
189 future: self.service.clone().oneshot(req),
190 }
191 }
192}
193
194pin_project! {
195 pub struct TowerToHyperServiceFuture<S, R>
197 where
198 S: tower_service::Service<R>,
199 {
200 #[pin]
201 future: Oneshot<S, R>,
202 }
203}
204
205impl<S, R> Future for TowerToHyperServiceFuture<S, R>
206where
207 S: tower_service::Service<R>,
208{
209 type Output = Result<S::Response, S::Error>;
210
211 #[inline]
212 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
213 self.project().future.poll(cx)
214 }
215}