use std::marker::PhantomData;
use std::time::Duration;
use http::header::{HeaderMap, HeaderName, HeaderValue};
use crate::call::CallEndpoint;
use crate::client::Client;
use crate::error::ClientError;
use crate::typed_response::TypedResponse;
pub struct RequestBuilder<'a, E: CallEndpoint> {
client: &'a Client,
args: E::Args,
extra_headers: HeaderMap,
query_params: Vec<(String, String)>,
timeout: Option<Duration>,
_endpoint: PhantomData<E>,
}
impl<'a, E: CallEndpoint> RequestBuilder<'a, E> {
pub(crate) fn new(client: &'a Client, args: E::Args) -> Self {
Self {
client,
args,
extra_headers: HeaderMap::new(),
query_params: Vec::new(),
timeout: None,
_endpoint: PhantomData,
}
}
pub fn header(mut self, name: impl Into<HeaderName>, value: impl Into<HeaderValue>) -> Self {
self.extra_headers.insert(name.into(), value.into());
self
}
pub fn query(mut self, key: &str, value: &str) -> Self {
self.query_params.push((key.to_string(), value.to_string()));
self
}
pub fn timeout(mut self, duration: Duration) -> Self {
self.timeout = Some(duration);
self
}
pub async fn send(self) -> Result<E::Response, ClientError> {
let overrides = CallOverrides {
extra_headers: if self.extra_headers.is_empty() {
None
} else {
Some(self.extra_headers)
},
query_string: None,
query_params: if self.query_params.is_empty() {
None
} else {
Some(self.query_params)
},
timeout: self.timeout,
};
let (_, body) = self
.client
.call_inner::<E>(&self.args, Some(&overrides))
.await?;
Ok(body)
}
pub async fn send_full(self) -> Result<TypedResponse<E::Response>, ClientError> {
let overrides = CallOverrides {
extra_headers: if self.extra_headers.is_empty() {
None
} else {
Some(self.extra_headers)
},
query_string: None,
query_params: if self.query_params.is_empty() {
None
} else {
Some(self.query_params)
},
timeout: self.timeout,
};
self.client
.call_inner::<E>(&self.args, Some(&overrides))
.await
.map(|(meta, body)| TypedResponse {
body,
status: meta.status,
headers: meta.headers,
})
}
}
pub(crate) struct CallOverrides {
pub extra_headers: Option<HeaderMap>,
pub query_string: Option<String>,
pub query_params: Option<Vec<(String, String)>>,
pub timeout: Option<Duration>,
}
pub(crate) struct ResponseMeta {
pub status: http::StatusCode,
pub headers: HeaderMap,
}