typeway_client/
request_builder.rs1use std::marker::PhantomData;
18use std::time::Duration;
19
20use http::header::{HeaderMap, HeaderName, HeaderValue};
21
22use crate::call::CallEndpoint;
23use crate::client::Client;
24use crate::error::ClientError;
25use crate::typed_response::TypedResponse;
26
27pub struct RequestBuilder<'a, E: CallEndpoint> {
34 client: &'a Client,
35 args: E::Args,
36 extra_headers: HeaderMap,
37 query_params: Vec<(String, String)>,
38 timeout: Option<Duration>,
39 _endpoint: PhantomData<E>,
40}
41
42impl<'a, E: CallEndpoint> RequestBuilder<'a, E> {
43 pub(crate) fn new(client: &'a Client, args: E::Args) -> Self {
44 Self {
45 client,
46 args,
47 extra_headers: HeaderMap::new(),
48 query_params: Vec::new(),
49 timeout: None,
50 _endpoint: PhantomData,
51 }
52 }
53
54 pub fn header(mut self, name: impl Into<HeaderName>, value: impl Into<HeaderValue>) -> Self {
56 self.extra_headers.insert(name.into(), value.into());
57 self
58 }
59
60 pub fn query(mut self, key: &str, value: &str) -> Self {
62 self.query_params.push((key.to_string(), value.to_string()));
63 self
64 }
65
66 pub fn timeout(mut self, duration: Duration) -> Self {
68 self.timeout = Some(duration);
69 self
70 }
71
72 pub async fn send(self) -> Result<E::Response, ClientError> {
76 let overrides = CallOverrides {
77 extra_headers: if self.extra_headers.is_empty() {
78 None
79 } else {
80 Some(self.extra_headers)
81 },
82 query_string: None,
83 query_params: if self.query_params.is_empty() {
84 None
85 } else {
86 Some(self.query_params)
87 },
88 timeout: self.timeout,
89 };
90 let (_, body) = self
91 .client
92 .call_inner::<E>(&self.args, Some(&overrides))
93 .await?;
94 Ok(body)
95 }
96
97 pub async fn send_full(self) -> Result<TypedResponse<E::Response>, ClientError> {
101 let overrides = CallOverrides {
102 extra_headers: if self.extra_headers.is_empty() {
103 None
104 } else {
105 Some(self.extra_headers)
106 },
107 query_string: None,
108 query_params: if self.query_params.is_empty() {
109 None
110 } else {
111 Some(self.query_params)
112 },
113 timeout: self.timeout,
114 };
115 self.client
116 .call_inner::<E>(&self.args, Some(&overrides))
117 .await
118 .map(|(meta, body)| TypedResponse {
119 body,
120 status: meta.status,
121 headers: meta.headers,
122 })
123 }
124}
125
126pub(crate) struct CallOverrides {
128 pub extra_headers: Option<HeaderMap>,
129 pub query_string: Option<String>,
131 pub query_params: Option<Vec<(String, String)>>,
133 pub timeout: Option<Duration>,
134}
135
136pub(crate) struct ResponseMeta {
138 pub status: http::StatusCode,
139 pub headers: HeaderMap,
140}