1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use std::future::Future;

use super::{MakeService, Service};

pub trait MapTarget<T> {
    type Target;

    fn map_target(&self, t: T) -> Self::Target;
}

impl<F, T, U> MapTarget<T> for F
where
    F: Fn(T) -> U,
{
    type Target = U;
    fn map_target(&self, t: T) -> U {
        (self)(t)
    }
}

pub struct MapTargetService<T, F> {
    pub f: F,
    pub inner: T,
}

impl<T, F, R> Service<R> for MapTargetService<T, F>
where
    F: MapTarget<R>,
    T: Service<F::Target>,
{
    type Response = T::Response;

    type Error = T::Error;

    type Future<'cx> = impl Future<Output = Result<Self::Response, Self::Error>> + 'cx
    where
        Self: 'cx,
        R: 'cx;

    fn call(&self, req: R) -> Self::Future<'_> {
        let req = self.f.map_target(req);
        self.inner.call(req)
    }
}

impl<FAC, F> MakeService for MapTargetService<FAC, F>
where
    FAC: MakeService,
    F: Clone,
{
    type Service = MapTargetService<FAC::Service, F>;
    type Error = FAC::Error;

    fn make_via_ref(&self, old: Option<&Self::Service>) -> Result<Self::Service, Self::Error> {
        Ok(MapTargetService {
            f: self.f.clone(),
            inner: self
                .inner
                .make_via_ref(old.map(|o| &o.inner))
                .map_err(Into::into)?,
        })
    }
}