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
use http_body_util::BodyExt;
use hyper::service::Service;

use crate::{async_trait, Body, Bytes, Error, Handler, Request, Response, Result};

/// Converts a hyper [`Service`] to a viz [`Handler`].
#[derive(Debug, Clone)]
pub struct ServiceHandler<S> {
    s: S,
}

impl<S> ServiceHandler<S> {
    /// Creates a new [`ServiceHandler`].
    pub fn new(s: S) -> Self {
        Self { s }
    }
}

#[async_trait]
impl<I, O, S> Handler<Request<I>> for ServiceHandler<S>
where
    I: Body + Send + Unpin + 'static,
    O: Body + Send + 'static,
    O::Data: Into<Bytes>,
    O::Error: Into<Error>,
    S: Service<Request<I>, Response = Response<O>> + Send + Sync + Clone + 'static,
    S::Future: Send,
    S::Error: Into<Error>,
{
    type Output = Result<Response>;

    async fn call(&self, req: Request<I>) -> Self::Output {
        self.s
            .call(req)
            .await
            .map(|resp| {
                resp.map(|body| {
                    body.map_frame(|f| f.map_data(Into::into))
                        .map_err(Into::into)
                        .boxed_unsync()
                })
                .map(Into::into)
            })
            .map_err(Into::into)
    }
}