use crate::{
error::{Error, Result},
http::{Headers, HttpRequest, HttpResponse, Method},
transport::transport::Transport,
};
pub(crate) struct ReqwestTransport {
client: reqwest::Client,
}
impl ReqwestTransport {
pub fn new(client: reqwest::Client) -> Self {
Self { client }
}
}
impl Transport for ReqwestTransport {
async fn send(&self, request: HttpRequest) -> Result<HttpResponse> {
let HttpRequest { method, url, headers, query } = request;
let mut request_builder = match method {
Method::Get => self.client.get(url),
};
if query.iter().next().is_some() {
let query_pairs = query.iter().collect::<Vec<_>>();
request_builder = request_builder.query(&query_pairs);
}
for (k, v) in headers.iter() {
request_builder = request_builder.header(k, v);
}
let resp = request_builder
.send()
.await
.map_err(|e| Error::Transport { source: Box::new(e) })?;
let status = resp.status().as_u16();
let mut headers = Headers::new();
for (name, value) in resp.headers().iter() {
if let Ok(s) = value.to_str() {
headers.insert(name.as_str(), s);
}
}
let body = resp
.bytes()
.await
.map_err(|e| Error::Transport { source: Box::new(e) })?
.to_vec();
Ok(HttpResponse { status, headers, body })
}
}