eiktyrner/
lib.rs

1use async_trait::async_trait;
2use hyper::client::HttpConnector;
3use hyper::Client;
4use hyper_tls::HttpsConnector;
5
6mod error;
7pub use error::Error;
8pub use http;
9
10pub mod content;
11pub use content::{RequestContent, ResponseContent};
12
13#[cfg(feature = "sse")]
14pub mod sse;
15
16#[cfg(feature = "sse")]
17pub use sse::Sse;
18
19#[async_trait]
20pub trait HttpClient
21where
22    Self: Send + Sync + Sized,
23{
24    async fn perform(
25        &self,
26        r: hyper::Request<hyper::Body>,
27    ) -> Result<hyper::Response<hyper::Body>, hyper::Error>;
28
29    async fn send<Req, Res>(
30        &self,
31        r: http::Request<Req>,
32    ) -> Result<http::Response<Res::Data>, Error>
33    where
34        Req: RequestContent + Send,
35        Res: ResponseContent,
36    {
37        let (mut parts, body) = r.into_parts();
38
39        body.apply_headers(&mut parts.headers);
40
41        let hyper_body: hyper::Body = body.into_body()?;
42        let request = hyper::Request::from_parts(parts, hyper_body);
43
44        let res = self.perform(request).await?;
45
46        Res::convert_response(res).await
47    }
48
49    fn https() -> HttpsClient {
50        HttpsClient::default()
51    }
52}
53
54pub struct HttpsClient {
55    http_client: Client<HttpsConnector<HttpConnector>>,
56}
57
58impl Default for HttpsClient {
59    fn default() -> Self {
60        let http_client = Client::builder().build::<_, hyper::Body>(HttpsConnector::new());
61        Self { http_client }
62    }
63}
64
65#[async_trait]
66impl HttpClient for HttpsClient {
67    async fn perform(
68        &self,
69        r: hyper::Request<hyper::Body>,
70    ) -> Result<hyper::Response<hyper::Body>, hyper::Error> {
71        self.http_client.request(r).await
72    }
73}