1use super::adapt::{Adapt, AdaptLayer, AdaptService};
2use crate::{Exc, ExchangeError};
3use futures::future::BoxFuture;
4use tower::{
5 util::{BoxCloneService, BoxService, MapErr},
6 Layer, Service,
7};
8
9use std::{
10 fmt,
11 future::Future,
12 marker::PhantomData,
13 task::{Context, Poll},
14};
15
16#[cfg(feature = "send")]
18pub mod send;
19
20pub trait Request: Sized {
22 type Response;
24}
25
26pub trait ExcService<R>
31where
32 R: Request,
33{
34 type Future: Future<Output = Result<R::Response, ExchangeError>>;
36
37 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), ExchangeError>>;
39
40 fn call(&mut self, req: R) -> Self::Future;
42
43 fn as_service(&mut self) -> AsService<'_, Self, R>
45 where
46 Self: Sized,
47 {
48 AsService {
49 inner: self,
50 _req: PhantomData,
51 }
52 }
53}
54
55impl<S, R> ExcService<R> for S
56where
57 S: Service<R, Response = R::Response, Error = ExchangeError>,
58 R: Request,
59{
60 type Future = S::Future;
61
62 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), ExchangeError>> {
63 Service::<R>::poll_ready(self, cx)
64 }
65
66 fn call(&mut self, req: R) -> Self::Future {
67 Service::<R>::call(self, req)
68 }
69}
70
71pub struct AsService<'a, S, R> {
73 inner: &'a mut S,
74 _req: PhantomData<R>,
75}
76
77impl<'a, S, R> fmt::Debug for AsService<'a, S, R>
78where
79 S: fmt::Debug,
80{
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 f.debug_struct("AsService")
83 .field("inner", &self.inner)
84 .finish()
85 }
86}
87
88impl<'a, S, R> Service<R> for AsService<'a, S, R>
89where
90 R: Request,
91 S: ExcService<R>,
92{
93 type Response = R::Response;
94
95 type Error = ExchangeError;
96
97 type Future = S::Future;
98
99 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
100 ExcService::<R>::poll_ready(self.inner, cx)
101 }
102
103 fn call(&mut self, req: R) -> Self::Future {
104 ExcService::<R>::call(self.inner, req)
105 }
106}
107
108pub struct IntoService<S, R> {
110 inner: S,
111 _req: PhantomData<R>,
112}
113
114impl<S, R> fmt::Debug for IntoService<S, R>
115where
116 S: fmt::Debug,
117{
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 f.debug_struct("IntoService")
120 .field("inner", &self.inner)
121 .finish()
122 }
123}
124
125impl<S, R> Clone for IntoService<S, R>
126where
127 S: Clone,
128{
129 fn clone(&self) -> Self {
130 Self {
131 inner: self.inner.clone(),
132 _req: PhantomData,
133 }
134 }
135}
136
137impl<S, R> Copy for IntoService<S, R> where S: Copy {}
138
139impl<S, R> Service<R> for IntoService<S, R>
140where
141 R: Request,
142 S: ExcService<R>,
143{
144 type Response = R::Response;
145
146 type Error = ExchangeError;
147
148 type Future = S::Future;
149
150 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
151 ExcService::<R>::poll_ready(&mut self.inner, cx)
152 }
153
154 fn call(&mut self, req: R) -> Self::Future {
155 ExcService::<R>::call(&mut self.inner, req)
156 }
157}
158
159pub trait ExcServiceExt<R>: ExcService<R>
161where
162 R: Request,
163{
164 fn into_service(self) -> IntoService<Self, R>
166 where
167 Self: Sized,
168 {
169 IntoService {
170 inner: self,
171 _req: PhantomData,
172 }
173 }
174
175 fn apply<L, R2>(self, layer: &L) -> L::Service
177 where
178 Self: Sized,
179 R2: Request,
180 L: Layer<Self>,
181 L::Service: ExcService<R2>,
182 {
183 layer.layer(self)
184 }
185
186 fn adapt<R2>(self) -> Adapt<Self, R, R2>
188 where
189 Self: Sized,
190 R2: Request,
191 Self: AdaptService<R, R2>,
192 {
193 self.apply(&AdaptLayer::default())
194 }
195
196 #[cfg(feature = "limit")]
198 fn rate_limited(
199 self,
200 num: u64,
201 per: std::time::Duration,
202 ) -> tower::limit::RateLimit<IntoService<Self, R>>
203 where
204 Self: Sized,
205 {
206 use tower::limit::RateLimitLayer;
207 self.into_service().apply(&RateLimitLayer::new(num, per))
208 }
209
210 #[cfg(feature = "retry")]
212 fn retry(
213 self,
214 max_duration: std::time::Duration,
215 ) -> tower::retry::Retry<crate::retry::Always, IntoService<Self, R>>
216 where
217 R: Clone,
218 Self: Sized + Clone,
219 {
220 use crate::retry::Always;
221 use tower::retry::RetryLayer;
222
223 self.into_service()
224 .apply(&RetryLayer::new(Always::with_max_duration(max_duration)))
225 }
226
227 fn boxed(self) -> BoxExcService<R>
229 where
230 Self: Sized + Send + 'static,
231 R: Send + 'static,
232 Self::Future: Send + 'static,
233 {
234 BoxExcService {
235 inner: BoxService::new(self.into_service()),
236 }
237 }
238
239 fn boxed_clone(&self) -> BoxCloneExcService<R>
241 where
242 R: Send + 'static,
243 Self: Sized + Clone + Send + 'static,
244 Self::Future: Send + 'static,
245 {
246 BoxCloneExcService {
247 inner: BoxCloneService::new(self.clone().into_service()),
248 }
249 }
250}
251
252impl<S, R> ExcServiceExt<R> for S
253where
254 S: ExcService<R>,
255 R: Request,
256{
257}
258
259type MapErrFn<E> = fn(E) -> ExchangeError;
260
261pub trait IntoExc<R>: Service<R, Response = R::Response>
263where
264 Self::Error: Into<ExchangeError>,
265 R: Request,
266{
267 fn into_exc(self) -> Exc<MapErr<Self, MapErrFn<Self::Error>>, R>
269 where
270 Self: Sized,
271 {
272 Exc::new(MapErr::new(self, Self::Error::into))
273 }
274}
275
276impl<S, R> IntoExc<R> for S
277where
278 S: Service<R, Response = R::Response>,
279 S::Error: Into<ExchangeError>,
280 R: Request,
281{
282}
283
284#[derive(Debug)]
286pub struct BoxExcService<R>
287where
288 R: Request,
289{
290 inner: BoxService<R, R::Response, ExchangeError>,
291}
292
293impl<R> Service<R> for BoxExcService<R>
294where
295 R: Request,
296{
297 type Response = R::Response;
298
299 type Error = ExchangeError;
300
301 type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
302
303 fn poll_ready(
304 &mut self,
305 cx: &mut std::task::Context<'_>,
306 ) -> std::task::Poll<Result<(), Self::Error>> {
307 Service::<R>::poll_ready(&mut self.inner, cx)
308 }
309
310 fn call(&mut self, req: R) -> Self::Future {
311 Service::<R>::call(&mut self.inner, req)
312 }
313}
314
315#[derive(Debug)]
317pub struct BoxCloneExcService<R>
318where
319 R: Request,
320{
321 inner: BoxCloneService<R, R::Response, ExchangeError>,
322}
323
324impl<R> Clone for BoxCloneExcService<R>
325where
326 R: Request,
327{
328 fn clone(&self) -> Self {
329 Self {
330 inner: self.inner.clone(),
331 }
332 }
333}
334
335impl<R> Service<R> for BoxCloneExcService<R>
336where
337 R: Request,
338{
339 type Response = R::Response;
340
341 type Error = ExchangeError;
342
343 type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
344
345 fn poll_ready(
346 &mut self,
347 cx: &mut std::task::Context<'_>,
348 ) -> std::task::Poll<Result<(), Self::Error>> {
349 Service::<R>::poll_ready(&mut self.inner, cx)
350 }
351
352 fn call(&mut self, req: R) -> Self::Future {
353 Service::<R>::call(&mut self.inner, req)
354 }
355}