1use std::future::Future;
2
3use super::{AsyncMakeService, MakeService, Service};
4
5pub trait MapTarget<T> {
6 type Target;
7
8 fn map_target(&self, t: T) -> Self::Target;
9}
10
11impl<F, T, U> MapTarget<T> for F
12where
13 F: Fn(T) -> U,
14{
15 type Target = U;
16
17 #[inline]
18 fn map_target(&self, t: T) -> U {
19 (self)(t)
20 }
21}
22
23pub struct MapTargetService<T, F> {
24 pub f: F,
25 pub inner: T,
26}
27
28impl<T, F, R> Service<R> for MapTargetService<T, F>
29where
30 F: MapTarget<R>,
31 T: Service<F::Target>,
32{
33 type Response = T::Response;
34
35 type Error = T::Error;
36
37 #[inline]
38 fn call(&self, req: R) -> impl Future<Output = Result<Self::Response, Self::Error>> {
39 let req = self.f.map_target(req);
40 self.inner.call(req)
41 }
42}
43
44impl<FAC, F> MakeService for MapTargetService<FAC, F>
45where
46 FAC: MakeService,
47 F: Clone,
48{
49 type Service = MapTargetService<FAC::Service, F>;
50 type Error = FAC::Error;
51
52 fn make_via_ref(&self, old: Option<&Self::Service>) -> Result<Self::Service, Self::Error> {
53 Ok(MapTargetService {
54 f: self.f.clone(),
55 inner: self
56 .inner
57 .make_via_ref(old.map(|o| &o.inner))
58 .map_err(Into::into)?,
59 })
60 }
61}
62
63impl<FAC, F> AsyncMakeService for MapTargetService<FAC, F>
64where
65 FAC: AsyncMakeService,
66 F: Clone,
67{
68 type Service = MapTargetService<FAC::Service, F>;
69 type Error = FAC::Error;
70
71 async fn make_via_ref(
72 &self,
73 old: Option<&Self::Service>,
74 ) -> Result<Self::Service, Self::Error> {
75 Ok(MapTargetService {
76 f: self.f.clone(),
77 inner: self
78 .inner
79 .make_via_ref(old.map(|o| &o.inner))
80 .await
81 .map_err(Into::into)?,
82 })
83 }
84}