1#[cfg(feature = "reqwest")]
2use crate::AgdbApiError;
3use crate::api_result::AgdbApiResult;
4use serde::Serialize;
5use serde::de::DeserializeOwned;
6
7#[allow(async_fn_in_trait)]
8pub trait HttpClient {
9 async fn delete(&self, uri: &str, token: &Option<String>) -> AgdbApiResult<u16>;
10 async fn get<T: DeserializeOwned + Send>(
11 &self,
12 uri: &str,
13 token: &Option<String>,
14 ) -> AgdbApiResult<(u16, T)>;
15 async fn post<T: Serialize, R: DeserializeOwned + Send>(
16 &self,
17 uri: &str,
18 json: &Option<T>,
19 token: &Option<String>,
20 ) -> AgdbApiResult<(u16, R)>;
21 async fn put<T: Serialize>(
22 &self,
23 uri: &str,
24 json: &Option<T>,
25 token: &Option<String>,
26 ) -> AgdbApiResult<u16>;
27}
28
29#[cfg(feature = "reqwest")]
30pub struct ReqwestClient {
31 pub client: reqwest::Client,
32}
33
34#[cfg(feature = "reqwest")]
35impl ReqwestClient {
36 #[allow(clippy::new_without_default)]
37 pub fn new() -> Self {
38 Self {
39 client: reqwest::Client::new(),
40 }
41 }
42
43 pub fn with_client(client: reqwest::Client) -> Self {
44 Self { client }
45 }
46}
47
48#[cfg(feature = "reqwest")]
49impl HttpClient for ReqwestClient {
50 async fn delete(&self, uri: &str, token: &Option<String>) -> AgdbApiResult<u16> {
51 let mut request = self.client.delete(uri);
52 if let Some(token) = token {
53 request = request.bearer_auth(token);
54 }
55 let response = request.send().await?;
56 let status = response.status().as_u16();
57 if response.status().is_success() {
58 Ok(status)
59 } else {
60 Err(AgdbApiError {
61 status,
62 description: response.text().await?,
63 })
64 }
65 }
66
67 async fn get<T: DeserializeOwned>(
68 &self,
69 uri: &str,
70 token: &Option<String>,
71 ) -> AgdbApiResult<(u16, T)> {
72 let mut request = self.client.get(uri);
73 if let Some(token) = token {
74 request = request.bearer_auth(token);
75 }
76 let response = request.send().await?;
77 let status = response.status().as_u16();
78 if response.status().is_success() {
79 let body = if response.content_length().unwrap_or(0) != 0 {
80 response.json::<T>().await?
81 } else {
82 serde_json::from_value(serde_json::Value::default())?
83 };
84 Ok((status, body))
85 } else {
86 Err(AgdbApiError {
87 status,
88 description: response.text().await?,
89 })
90 }
91 }
92
93 async fn post<T: Serialize, R: DeserializeOwned>(
94 &self,
95 uri: &str,
96 json: &Option<T>,
97 token: &Option<String>,
98 ) -> AgdbApiResult<(u16, R)> {
99 let mut request = self.client.post(uri);
100 if let Some(token) = token {
101 request = request.bearer_auth(token);
102 }
103 if let Some(json) = json {
104 request = request.json(json);
105 }
106 let response = request.send().await?;
107 let status = response.status().as_u16();
108 if response.status().is_success() {
109 let body = if response.content_length().unwrap_or(0) != 0 {
110 response.json::<R>().await?
111 } else {
112 serde_json::from_value(serde_json::Value::default())?
113 };
114 Ok((status, body))
115 } else {
116 Err(AgdbApiError {
117 status,
118 description: response.text().await?,
119 })
120 }
121 }
122
123 async fn put<T: Serialize>(
124 &self,
125 uri: &str,
126 json: &Option<T>,
127 token: &Option<String>,
128 ) -> AgdbApiResult<u16> {
129 let mut request = self.client.put(uri);
130 if let Some(json) = json {
131 request = request.json(json);
132 }
133 if let Some(token) = token {
134 request = request.bearer_auth(token);
135 }
136 let response = request.send().await?;
137 let status = response.status().as_u16();
138 if response.status().is_success() {
139 Ok(status)
140 } else {
141 Err(AgdbApiError {
142 status,
143 description: response.text().await?,
144 })
145 }
146 }
147}