reqwest_builder/
trait_impl.rs1use crate::{
2 errors::ReqwestBuilderError,
3 serialization::{
4 construct_url_safe, serialize_to_form_params, serialize_to_form_params_safe,
5 serialize_to_header_map, serialize_to_header_map_safe,
6 },
7 types::{QueryParams, RequestBody},
8};
9use serde::Serialize;
10use url::Url;
11
12pub trait IntoReqwestBuilder
17where
18 Self: Sized + Serialize,
19{
20 type Headers: Serialize + Clone;
22
23 fn method(&self) -> http::Method;
25
26 fn endpoint(&self) -> String;
28
29 fn headers(&self) -> Option<Self::Headers> {
31 None
32 }
33
34 fn body(&self) -> RequestBody {
36 RequestBody::Json
37 }
38
39 fn query_params(&self) -> Option<QueryParams> {
41 None
42 }
43
44 fn create_multipart_form(&self) -> Option<reqwest::multipart::Form> {
46 None
47 }
48
49 fn into_reqwest_builder(
53 self,
54 client: &reqwest_middleware::ClientWithMiddleware,
55 base_url: &Url,
56 ) -> reqwest_middleware::RequestBuilder {
57 let url = construct_url_safe(base_url, &self.endpoint());
59 let mut builder = client.request(self.method(), &url);
60
61 if let Some(params) = self.query_params() {
63 builder = builder.query(¶ms);
64 }
65
66 builder = self.add_body_to_builder(builder);
68
69 if let Some(headers) = self.headers() {
71 let header_map = serialize_to_header_map_safe(&headers);
72 builder = builder.headers(header_map);
73 }
74
75 builder
76 }
77
78 fn try_into_reqwest_builder(
82 self,
83 client: &reqwest_middleware::ClientWithMiddleware,
84 base_url: &Url,
85 ) -> std::result::Result<reqwest_middleware::RequestBuilder, ReqwestBuilderError> {
86 let url = construct_url_safe(base_url, &self.endpoint());
88 let mut builder = client.request(self.method(), &url);
89
90 if let Some(params) = self.query_params() {
92 builder = builder.query(¶ms);
93 }
94
95 builder = self.try_add_body_to_builder(builder)?;
97
98 if let Some(headers) = self.headers() {
100 let header_map = serialize_to_header_map(&headers)?;
101 builder = builder.headers(header_map);
102 }
103
104 Ok(builder)
105 }
106
107 fn add_body_to_builder(
109 &self,
110 mut builder: reqwest_middleware::RequestBuilder,
111 ) -> reqwest_middleware::RequestBuilder {
112 match self.body() {
113 RequestBody::Json => {
114 if let Ok(json_str) = serde_json::to_string(self) {
116 if json_str != "{}" {
117 builder = builder.json(self);
118 }
119 } else {
120 builder = builder.json(self);
121 }
122 }
123 RequestBody::Form => {
124 let params = serialize_to_form_params_safe(self);
125 builder = builder.form(¶ms);
126 }
127 RequestBody::Multipart => {
128 if let Some(form) = self.create_multipart_form() {
129 builder = builder.multipart(form);
130 }
131 }
132 RequestBody::None => {
133 }
135 }
136 builder
137 }
138
139 fn try_add_body_to_builder(
141 &self,
142 mut builder: reqwest_middleware::RequestBuilder,
143 ) -> std::result::Result<reqwest_middleware::RequestBuilder, ReqwestBuilderError> {
144 match self.body() {
145 RequestBody::Json => {
146 let json_str = serde_json::to_string(self).map_err(ReqwestBuilderError::from)?;
147 if json_str != "{}" {
148 builder = builder.json(self);
149 }
150 }
151 RequestBody::Form => {
152 let params = serialize_to_form_params(self)?;
153 builder = builder.form(¶ms);
154 }
155 RequestBody::Multipart => {
156 if let Some(form) = self.create_multipart_form() {
157 builder = builder.multipart(form);
158 }
159 }
160 RequestBody::None => {
161 }
163 }
164 Ok(builder)
165 }
166}
167
168pub fn query_param_helper<T>(
171 value: &T,
172 param_name: &str,
173 params: &mut std::collections::HashMap<String, String>,
174) where
175 T: QueryParamValue,
176{
177 value.add_to_params(param_name, params);
178}
179
180pub trait QueryParamValue {
182 fn add_to_params(
183 &self,
184 param_name: &str,
185 params: &mut std::collections::HashMap<String, String>,
186 );
187}
188
189impl<T: std::fmt::Display> QueryParamValue for Option<T> {
191 fn add_to_params(
192 &self,
193 param_name: &str,
194 params: &mut std::collections::HashMap<String, String>,
195 ) {
196 if let Some(value) = self {
197 params.insert(param_name.to_string(), value.to_string());
198 }
199 }
200}
201
202impl QueryParamValue for String {
205 fn add_to_params(
206 &self,
207 param_name: &str,
208 params: &mut std::collections::HashMap<String, String>,
209 ) {
210 params.insert(param_name.to_string(), self.clone());
211 }
212}
213
214impl QueryParamValue for &str {
215 fn add_to_params(
216 &self,
217 param_name: &str,
218 params: &mut std::collections::HashMap<String, String>,
219 ) {
220 params.insert(param_name.to_string(), self.to_string());
221 }
222}
223
224impl QueryParamValue for u32 {
225 fn add_to_params(
226 &self,
227 param_name: &str,
228 params: &mut std::collections::HashMap<String, String>,
229 ) {
230 params.insert(param_name.to_string(), self.to_string());
231 }
232}
233
234impl QueryParamValue for u64 {
235 fn add_to_params(
236 &self,
237 param_name: &str,
238 params: &mut std::collections::HashMap<String, String>,
239 ) {
240 params.insert(param_name.to_string(), self.to_string());
241 }
242}
243
244impl QueryParamValue for i32 {
245 fn add_to_params(
246 &self,
247 param_name: &str,
248 params: &mut std::collections::HashMap<String, String>,
249 ) {
250 params.insert(param_name.to_string(), self.to_string());
251 }
252}
253
254impl QueryParamValue for i64 {
255 fn add_to_params(
256 &self,
257 param_name: &str,
258 params: &mut std::collections::HashMap<String, String>,
259 ) {
260 params.insert(param_name.to_string(), self.to_string());
261 }
262}
263
264impl QueryParamValue for bool {
265 fn add_to_params(
266 &self,
267 param_name: &str,
268 params: &mut std::collections::HashMap<String, String>,
269 ) {
270 params.insert(param_name.to_string(), self.to_string());
271 }
272}