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
64
65
66
67
68
69
70
71
72
73
74
75
76
use std::{error::Error as StdError, future::Future};
use bytes::Bytes;
use hyper::body::HttpBody;
use tower::{Service, ServiceExt};
use crate::{body::BodyStream, Endpoint, Error, Request, Response, Result};
#[cfg_attr(docsrs, doc(cfg(feature = "tower-compat")))]
pub trait TowerCompatExt {
fn compat<ResBody, Err, Fut>(self) -> TowerCompatEndpoint<Self>
where
ResBody: HttpBody + Send + 'static,
ResBody::Data: Into<Bytes> + Send + 'static,
ResBody::Error: StdError + Send + Sync + 'static,
Err: StdError + Send + Sync + 'static,
Self: Service<
http::Request<hyper::Body>,
Response = hyper::Response<ResBody>,
Error = Err,
Future = Fut,
> + Clone
+ Send
+ Sync
+ Sized
+ 'static,
Fut: Future<Output = Result<hyper::Response<ResBody>, Err>> + Send + 'static,
{
TowerCompatEndpoint(self)
}
}
impl<T> TowerCompatExt for T {}
#[cfg_attr(docsrs, doc(cfg(feature = "tower-compat")))]
pub struct TowerCompatEndpoint<Svc>(Svc);
#[async_trait::async_trait]
impl<Svc, ResBody, Err, Fut> Endpoint for TowerCompatEndpoint<Svc>
where
ResBody: HttpBody + Send + 'static,
ResBody::Data: Into<Bytes> + Send + 'static,
ResBody::Error: StdError + Send + Sync + 'static,
Err: StdError + Send + Sync + 'static,
Svc: Service<
http::Request<hyper::Body>,
Response = hyper::Response<ResBody>,
Error = Err,
Future = Fut,
> + Clone
+ Send
+ Sync
+ 'static,
Fut: Future<Output = Result<hyper::Response<ResBody>, Err>> + Send + 'static,
{
type Output = Result<Response>;
async fn call(&self, req: Request) -> Self::Output {
let mut svc = self.0.clone();
svc.ready().await.map_err(Error::internal_server_error)?;
let hyper_req: http::Request<hyper::Body> = req.into();
let hyper_resp = svc
.call(hyper_req.map(Into::into))
.await
.map_err(Error::internal_server_error)?;
Ok(hyper_resp
.map(|body| hyper::Body::wrap_stream(BodyStream::new(body)))
.into())
}
}