use crate::{client::Client as RustifyClient, errors::ClientError};
use async_trait::async_trait;
use http::{Request, Response};
use std::convert::TryFrom;
pub struct Client {
pub http: reqwest::Client,
pub base: String,
}
impl Client {
pub fn new(base: &str, http: reqwest::Client) -> Self {
Client {
base: base.to_string(),
http,
}
}
pub fn default(base: &str) -> Self {
Client {
base: base.to_string(),
http: reqwest::Client::default(),
}
}
}
#[async_trait]
impl RustifyClient for Client {
fn base(&self) -> &str {
self.base.as_str()
}
#[allow(clippy::blocks_in_conditions)]
#[instrument(skip(self, req), err)]
async fn send(&self, req: Request<Vec<u8>>) -> Result<Response<Vec<u8>>, ClientError> {
let request = reqwest::Request::try_from(req)
.map_err(|e| ClientError::ReqwestBuildError { source: e })?;
let url_err = request.url().to_string();
let method_err = request.method().to_string();
let response = self
.http
.execute(request)
.await
.map_err(|e| ClientError::RequestError {
source: e.into(),
url: url_err,
method: method_err,
})?;
let status_code = response.status().as_u16();
let mut http_resp = http::Response::builder().status(status_code);
for v in response.headers().into_iter() {
http_resp = http_resp.header(v.0, v.1);
}
http_resp
.body(
response
.bytes()
.await
.map_err(|e| ClientError::ResponseError { source: e.into() })?
.to_vec(),
)
.map_err(|e| ClientError::ResponseError { source: e.into() })
}
}