1use bytes::Bytes;
2use http_body_util::{BodyExt, Full};
3use hyper::{Method, Request};
4
5use hyper_tls::HttpsConnector;
6use hyper_util::client::legacy::{Client as HyperClient, connect::HttpConnector};
7use hyper_util::rt::TokioExecutor;
8use serde::Serialize;
9use serde::de::DeserializeOwned;
10
11#[derive(Clone)]
12#[allow(dead_code)]
13pub struct Client {
14 client: HyperClient<HttpsConnector<HttpConnector>, Full<Bytes>>,
15}
16
17#[allow(dead_code)]
18impl Client {
19 pub fn new() -> Self {
20 let https = HttpsConnector::new();
21 let client = HyperClient::builder(TokioExecutor::new()).build::<_, Full<Bytes>>(https);
22 Self { client }
23 }
24
25 pub async fn fetch(
26 &self,
27 url: &str,
28 ) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
29 let req = Request::builder()
31 .method(Method::GET)
32 .uri(url)
33 .body(Full::new(Bytes::new()))?;
34
35 let resp = self.client.request(req).await?;
36
37 let body_bytes = resp.into_body().collect().await?.to_bytes();
38
39 Ok(String::from_utf8_lossy(&body_bytes).to_string())
40 }
41
42 async fn send_json<T: Serialize + ?Sized, U: DeserializeOwned>(
43 &self,
44 method: Method,
45 url: &str,
46 body: &T,
47 ) -> Result<U, Box<dyn std::error::Error + Send + Sync>> {
48 let body_bytes = serde_json::to_vec(body)?;
49 let req = Request::builder()
50 .method(method)
51 .uri(url)
52 .header("Content-Type", "application/json")
53 .body(Full::new(Bytes::from(body_bytes)))?;
54 let resp = self.client.request(req).await?;
55 let body_bytes = resp.into_body().collect().await?.to_bytes();
56 Ok(serde_json::from_slice(&body_bytes)?)
57 }
58
59 pub async fn get<T: DeserializeOwned>(
60 &self,
61 url: &str,
62 ) -> Result<T, Box<dyn std::error::Error + Send + Sync>> {
63 let req = Request::builder()
64 .method(Method::GET)
65 .uri(url)
66 .body(Full::new(Bytes::new()))?;
67
68 let resp = self.client.request(req).await?;
69
70 let body_bytes = resp.into_body().collect().await?.to_bytes();
71
72 let parsed: T = serde_json::from_slice(&body_bytes)?;
73 Ok(parsed)
74 }
75
76 pub async fn post<T: Serialize + ?Sized, U: DeserializeOwned>(
77 &self,
78 url: &str,
79 body: &T,
80 ) -> Result<U, Box<dyn std::error::Error + Send + Sync>> {
81 self.send_json(Method::POST, url, body).await
82 }
83
84 pub async fn put<T: Serialize + ?Sized, U: DeserializeOwned>(
85 &self,
86 url: &str,
87 body: &T,
88 ) -> Result<U, Box<dyn std::error::Error + Send + Sync>> {
89 self.send_json(Method::PUT, url, body).await
90 }
91
92 pub async fn patch<T: Serialize + ?Sized, U: DeserializeOwned>(
93 &self,
94 url: &str,
95 body: &T,
96 ) -> Result<U, Box<dyn std::error::Error + Send + Sync>> {
97 self.send_json(Method::PATCH, url, body).await
98 }
99
100 pub async fn delete<U: DeserializeOwned>(
101 &self,
102 url: &str,
103 ) -> Result<U, Box<dyn std::error::Error + Send + Sync>> {
104 let req = Request::builder()
105 .method(Method::DELETE)
106 .uri(url)
107 .body(Full::new(Bytes::new()))?;
108
109 let resp = self.client.request(req).await?;
110
111 let body_bytes = resp.into_body().collect().await?.to_bytes();
112
113 Ok(serde_json::from_slice(&body_bytes)?)
114 }
115
116 pub async fn delete_with_payload<T: Serialize + ?Sized, U: DeserializeOwned>(
117 &self,
118 url: &str,
119 body: &T,
120 ) -> Result<U, Box<dyn std::error::Error + Send + Sync>> {
121 self.send_json(Method::DELETE, url, body).await
122 }
123}