agdb_api/
http_client.rs

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}