gitlab_time_report/fetch_api/
http_requests.rs1#![cfg(not(tarpaulin_include))]
6
7use super::fetch_options::FetchOptions;
8#[cfg(test)]
9use mockall::automock;
10use reqwest::StatusCode;
11use reqwest::blocking::Client;
12use thiserror::Error;
13
14#[cfg_attr(test, automock)]
16pub(super) trait HttpFetcher {
17 fn http_post_request(
19 &self,
20 url: &str,
21 payload: serde_json::Value,
22 options: &FetchOptions,
23 ) -> Result<String, NetworkError>;
24}
25
26impl HttpFetcher for Client {
27 fn http_post_request(
28 &self,
29 url: &str,
30 payload: serde_json::Value,
31 options: &FetchOptions,
32 ) -> Result<String, NetworkError> {
33 let mut request = self.post(url).json(&payload);
34
35 if let Some(token) = &options.token {
37 request = request.bearer_auth(token);
38 }
39
40 Ok(request.send()?.error_for_status()?.text()?)
41 }
42}
43
44#[derive(Debug, Clone, Error)]
47pub enum NetworkError {
48 #[error("HTTP error: {0}")]
49 StatusCode(StatusCode),
50 #[error("Connection to {0} failed")]
51 Connection(String),
52}
53
54impl From<reqwest::Error> for NetworkError {
56 fn from(e: reqwest::Error) -> Self {
57 if e.is_connect() {
58 return Self::Connection(
59 e.url()
60 .expect("Should have a connection URL here")
61 .to_string(),
62 );
63 }
64 let status = e.status().expect("Should have a status code here");
65 Self::StatusCode(status)
66 }
67}