#![cfg(not(tarpaulin_include))]
use super::fetch_options::FetchOptions;
#[cfg(test)]
use mockall::automock;
use reqwest::StatusCode;
use reqwest::blocking::Client;
use thiserror::Error;
#[cfg_attr(test, automock)]
pub(super) trait HttpFetcher {
fn http_post_request(
&self,
url: &str,
payload: serde_json::Value,
options: &FetchOptions,
) -> Result<String, NetworkError>;
}
impl HttpFetcher for Client {
fn http_post_request(
&self,
url: &str,
payload: serde_json::Value,
options: &FetchOptions,
) -> Result<String, NetworkError> {
let mut request = self.post(url).json(&payload);
if let Some(token) = &options.token {
request = request.bearer_auth(token);
}
Ok(request.send()?.error_for_status()?.text()?)
}
}
#[derive(Debug, Clone, Error)]
pub enum NetworkError {
#[error("HTTP error: {0}")]
StatusCode(StatusCode),
#[error("Connection to {0} failed")]
Connection(String),
}
impl From<reqwest::Error> for NetworkError {
fn from(e: reqwest::Error) -> Self {
if e.is_connect() {
return Self::Connection(
e.url()
.expect("Should have a connection URL here")
.to_string(),
);
}
let status = e.status().expect("Should have a status code here");
Self::StatusCode(status)
}
}