1use crate::body::Body;
4use crate::client::HttpClient;
5use crate::error::HttpError;
6use crate::response::Response;
7use crate::streaming::StreamingResponse;
8
9pub struct RequestBuilder<'a> {
11 client: &'a mut HttpClient,
12 method: String,
13 path: String,
14 headers: Vec<(String, String)>,
15 body: Body,
16}
17
18impl<'a> RequestBuilder<'a> {
19 pub(crate) fn new(client: &'a mut HttpClient, method: &str, path: &str) -> Self {
20 Self {
21 client,
22 method: method.to_string(),
23 path: path.to_string(),
24 headers: Vec::new(),
25 body: Body::Empty,
26 }
27 }
28
29 pub fn header(mut self, name: &str, value: &str) -> Self {
31 self.headers.push((name.to_string(), value.to_string()));
32 self
33 }
34
35 pub fn body(mut self, body: impl Into<Body>) -> Self {
37 self.body = body.into();
38 self
39 }
40
41 pub async fn send(mut self) -> Result<Response, HttpError> {
43 self.inject_accept_encoding();
44
45 let extra: Vec<(&str, &str)> = self
46 .headers
47 .iter()
48 .map(|(k, v)| (k.as_str(), v.as_str()))
49 .collect();
50
51 let body_bytes = match &self.body {
52 Body::Empty => None,
53 Body::Bytes(b) => Some(b.as_ref()),
54 };
55
56 self.client
57 .send_request(&self.method, &self.path, &extra, body_bytes)
58 .await
59 }
60
61 pub async fn send_streaming(mut self) -> Result<StreamingResponse<'a>, HttpError> {
70 self.inject_accept_encoding();
71
72 let extra: Vec<(&str, &str)> = self
73 .headers
74 .iter()
75 .map(|(k, v)| (k.as_str(), v.as_str()))
76 .collect();
77
78 let body_bytes = match &self.body {
79 Body::Empty => None,
80 Body::Bytes(b) => Some(b.as_ref()),
81 };
82
83 self.client
84 .send_request_streaming(&self.method, &self.path, &extra, body_bytes)
85 .await
86 }
87
88 fn inject_accept_encoding(&mut self) {
91 let has_ae = self
92 .headers
93 .iter()
94 .any(|(name, _)| name.eq_ignore_ascii_case("accept-encoding"));
95 if !has_ae && let Some(ae) = crate::compress::accept_encoding_value() {
96 self.headers
97 .push(("accept-encoding".to_string(), ae.to_string()));
98 }
99 }
100}