use crate::body::Body;
use crate::client::HttpClient;
use crate::error::HttpError;
use crate::response::Response;
use crate::streaming::StreamingResponse;
pub struct RequestBuilder<'a> {
client: &'a mut HttpClient,
method: String,
path: String,
headers: Vec<(String, String)>,
body: Body,
}
impl<'a> RequestBuilder<'a> {
pub(crate) fn new(client: &'a mut HttpClient, method: &str, path: &str) -> Self {
Self {
client,
method: method.to_string(),
path: path.to_string(),
headers: Vec::new(),
body: Body::Empty,
}
}
pub fn header(mut self, name: &str, value: &str) -> Self {
self.headers.push((name.to_string(), value.to_string()));
self
}
pub fn body(mut self, body: impl Into<Body>) -> Self {
self.body = body.into();
self
}
pub async fn send(mut self) -> Result<Response, HttpError> {
self.inject_accept_encoding();
let extra: Vec<(&str, &str)> = self
.headers
.iter()
.map(|(k, v)| (k.as_str(), v.as_str()))
.collect();
let body_bytes = match &self.body {
Body::Empty => None,
Body::Bytes(b) => Some(b.as_ref()),
};
self.client
.send_request(&self.method, &self.path, &extra, body_bytes)
.await
}
pub async fn send_streaming(mut self) -> Result<StreamingResponse<'a>, HttpError> {
self.inject_accept_encoding();
let extra: Vec<(&str, &str)> = self
.headers
.iter()
.map(|(k, v)| (k.as_str(), v.as_str()))
.collect();
let body_bytes = match &self.body {
Body::Empty => None,
Body::Bytes(b) => Some(b.as_ref()),
};
self.client
.send_request_streaming(&self.method, &self.path, &extra, body_bytes)
.await
}
fn inject_accept_encoding(&mut self) {
let has_ae = self
.headers
.iter()
.any(|(name, _)| name.eq_ignore_ascii_case("accept-encoding"));
if !has_ae && let Some(ae) = crate::compress::accept_encoding_value() {
self.headers
.push(("accept-encoding".to_string(), ae.to_string()));
}
}
}