1use super::{
2 super::{
3 super::{EndpointsProvider, IpAddrWithPort, ServiceName},
4 callbacks::CallbacksBuilder,
5 request_call, ApiResult, Authorization, CallbackContext, ExtendedCallbackContext, HttpClient, ResolveAnswers,
6 ResponseError, SimplifiedCallbackContext, SyncResponse,
7 },
8 multipart::SyncMultipart,
9 request_metadata::RequestMetadata,
10 Idempotent, QueryPair, QueryPairKey, QueryPairValue, SyncInnerRequest,
11};
12use anyhow::Result as AnyResult;
13use assert_impl::assert_impl;
14use mime::{Mime, APPLICATION_JSON, APPLICATION_OCTET_STREAM, APPLICATION_WWW_FORM_URLENCODED};
15use qiniu_http::{
16 header::{IntoHeaderName, ACCEPT, CONTENT_TYPE},
17 Extensions, HeaderMap, HeaderName, HeaderValue, Method, Reset, ResponseParts, StatusCode, SyncRequestBody,
18 TransferProgressInfo, UserAgent, Version,
19};
20use serde::Serialize;
21use serde_json::Result as JsonResult;
22use std::{
23 borrow::{Borrow, Cow},
24 fmt::Debug,
25 io::{Read, Result as IoResult},
26 mem::take,
27 time::Duration,
28};
29
30#[cfg(feature = "async")]
31use {
32 super::{
33 super::{async_request_call, AsyncResponse},
34 multipart::AsyncMultipart,
35 AsyncInnerRequest,
36 },
37 futures::io::AsyncRead,
38 qiniu_http::{AsyncRequestBody, AsyncReset},
39};
40
41#[derive(Default, Debug)]
45pub struct RequestBuilderParts<'r> {
46 callbacks: CallbacksBuilder<'r>,
47 metadata: RequestMetadata<'r>,
48 extensions: Extensions,
49 appended_user_agent: UserAgent,
50}
51
52impl<'r> RequestBuilderParts<'r> {
53 #[inline]
55 pub fn use_https(&mut self, use_https: bool) -> &mut Self {
56 self.metadata.use_https = Some(use_https);
57 self
58 }
59
60 #[inline]
62 pub fn version(&mut self, version: Version) -> &mut Self {
63 self.metadata.version = version;
64 self
65 }
66
67 #[inline]
69 pub fn path(&mut self, path: impl Into<Cow<'r, str>>) -> &mut Self {
70 self.metadata.path = path.into();
71 self
72 }
73
74 #[inline]
76 pub fn headers(&mut self, headers: impl Into<Cow<'r, HeaderMap>>) -> &mut Self {
77 self.metadata.headers = headers.into();
78 self
79 }
80
81 #[inline]
83 pub fn set_header(&mut self, header_name: impl IntoHeaderName, header_value: impl Into<HeaderValue>) -> &mut Self {
84 self.metadata.headers.to_mut().insert(header_name, header_value.into());
85 self
86 }
87
88 fn set_content_type(&mut self, content_type: Option<Mime>) -> &mut Self {
89 self.set_header(
90 CONTENT_TYPE,
91 HeaderValue::from_str(content_type.as_ref().unwrap_or(&APPLICATION_OCTET_STREAM).as_ref()).unwrap(),
92 )
93 }
94
95 #[inline]
97 pub fn accept_json(&mut self) -> &mut Self {
98 self.set_accept(APPLICATION_JSON)
99 }
100
101 #[inline]
103 pub fn accept_application_octet_stream(&mut self) -> &mut Self {
104 self.set_accept(APPLICATION_OCTET_STREAM)
105 }
106
107 fn set_accept(&mut self, accept: Mime) -> &mut Self {
108 self.set_header(ACCEPT, HeaderValue::from_str(accept.as_ref()).unwrap())
109 }
110
111 #[inline]
113 pub fn query(&mut self, query: impl Into<Cow<'r, str>>) -> &mut Self {
114 self.metadata.query = query.into();
115 self
116 }
117
118 #[inline]
120 pub fn query_pairs(&mut self, query_pairs: impl Into<Vec<QueryPair<'r>>>) -> &mut Self {
121 self.metadata.query_pairs = query_pairs.into();
122 self
123 }
124
125 #[inline]
127 pub fn append_query_pair(
128 &mut self,
129 query_pair_key: impl Into<QueryPairKey<'r>>,
130 query_pair_value: impl Into<QueryPairValue<'r>>,
131 ) -> &mut Self {
132 self.metadata
133 .query_pairs
134 .push((query_pair_key.into(), query_pair_value.into()));
135 self
136 }
137
138 #[inline]
140 pub fn appended_user_agent(&mut self, user_agent: impl Into<UserAgent>) -> &mut Self {
141 self.appended_user_agent = user_agent.into();
142 self
143 }
144
145 #[inline]
147 pub fn authorization(&mut self, authorization: Authorization<'r>) -> &mut Self {
148 self.metadata.authorization = Some(authorization);
149 self
150 }
151
152 #[inline]
154 pub fn idempotent(&mut self, idempotent: Idempotent) -> &mut Self {
155 self.metadata.idempotent = idempotent;
156 self
157 }
158
159 #[inline]
161 pub fn extensions(&mut self, extensions: Extensions) -> &mut Self {
162 self.extensions = extensions;
163 self
164 }
165
166 #[inline]
168 pub fn add_extension<T: Send + Sync + 'static>(&mut self, val: T) -> &mut Self {
169 self.extensions.insert(val);
170 self
171 }
172
173 #[inline]
175 pub fn on_uploading_progress(
176 &mut self,
177 callback: impl Fn(&dyn SimplifiedCallbackContext, TransferProgressInfo<'_>) -> AnyResult<()> + Send + Sync + 'r,
178 ) -> &mut Self {
179 self.callbacks.on_uploading_progress(callback);
180 self
181 }
182
183 #[inline]
185
186 pub fn on_receive_response_status(
187 &mut self,
188 callback: impl Fn(&dyn SimplifiedCallbackContext, StatusCode) -> AnyResult<()> + Send + Sync + 'r,
189 ) -> &mut Self {
190 self.callbacks.on_receive_response_status(callback);
191 self
192 }
193
194 #[inline]
196 pub fn on_receive_response_header(
197 &mut self,
198 callback: impl Fn(&dyn SimplifiedCallbackContext, &HeaderName, &HeaderValue) -> AnyResult<()> + Send + Sync + 'r,
199 ) -> &mut Self {
200 self.callbacks.on_receive_response_header(callback);
201 self
202 }
203
204 #[inline]
206 pub fn on_to_resolve_domain(
207 &mut self,
208 callback: impl Fn(&mut dyn CallbackContext, &str) -> AnyResult<()> + Send + Sync + 'r,
209 ) -> &mut Self {
210 self.callbacks.on_to_resolve_domain(callback);
211 self
212 }
213
214 #[inline]
216 pub fn on_domain_resolved(
217 &mut self,
218 callback: impl Fn(&mut dyn CallbackContext, &str, &ResolveAnswers) -> AnyResult<()> + Send + Sync + 'r,
219 ) -> &mut Self {
220 self.callbacks.on_domain_resolved(callback);
221 self
222 }
223
224 #[inline]
226 pub fn on_to_choose_ips(
227 &mut self,
228 callback: impl Fn(&mut dyn CallbackContext, &[IpAddrWithPort]) -> AnyResult<()> + Send + Sync + 'r,
229 ) -> &mut Self {
230 self.callbacks.on_to_choose_ips(callback);
231 self
232 }
233
234 #[inline]
236 pub fn on_ips_chosen(
237 &mut self,
238 callback: impl Fn(&mut dyn CallbackContext, &[IpAddrWithPort], &[IpAddrWithPort]) -> AnyResult<()>
239 + Send
240 + Sync
241 + 'r,
242 ) -> &mut Self {
243 self.callbacks.on_ips_chosen(callback);
244 self
245 }
246
247 #[inline]
249 pub fn on_before_request_signed(
250 &mut self,
251 callback: impl Fn(&mut dyn ExtendedCallbackContext) -> AnyResult<()> + Send + Sync + 'r,
252 ) -> &mut Self {
253 self.callbacks.on_before_request_signed(callback);
254 self
255 }
256
257 #[inline]
259 pub fn on_after_request_signed(
260 &mut self,
261 callback: impl Fn(&mut dyn ExtendedCallbackContext) -> AnyResult<()> + Send + Sync + 'r,
262 ) -> &mut Self {
263 self.callbacks.on_after_request_signed(callback);
264 self
265 }
266
267 #[inline]
269 pub fn on_response(
270 &mut self,
271 callback: impl Fn(&mut dyn ExtendedCallbackContext, &ResponseParts) -> AnyResult<()> + Send + Sync + 'r,
272 ) -> &mut Self {
273 self.callbacks.on_response(callback);
274 self
275 }
276
277 #[inline]
279 pub fn on_error(
280 &mut self,
281 callback: impl Fn(&mut dyn ExtendedCallbackContext, &mut ResponseError) -> AnyResult<()> + Send + Sync + 'r,
282 ) -> &mut Self {
283 self.callbacks.on_error(callback);
284 self
285 }
286
287 #[inline]
289 pub fn on_before_backoff(
290 &mut self,
291 callback: impl Fn(&mut dyn ExtendedCallbackContext, Duration) -> AnyResult<()> + Send + Sync + 'r,
292 ) -> &mut Self {
293 self.callbacks.on_before_backoff(callback);
294 self
295 }
296
297 #[inline]
299 pub fn on_after_backoff(
300 &mut self,
301 callback: impl Fn(&mut dyn ExtendedCallbackContext, Duration) -> AnyResult<()> + Send + Sync + 'r,
302 ) -> &mut Self {
303 self.callbacks.on_after_backoff(callback);
304 self
305 }
306
307 #[inline]
309 pub fn build(self) -> RequestParts<'r> {
310 RequestParts {
311 metadata: self.metadata,
312 extensions: self.extensions,
313 appended_user_agent: self.appended_user_agent,
314 }
315 }
316
317 #[allow(dead_code)]
318 fn ignore() {
319 assert_impl!(Send: Self);
320 assert_impl!(Sync: Self);
321 }
322}
323
324#[derive(Debug)]
328pub struct RequestBuilder<'r, B: 'r, E: 'r> {
329 http_client: &'r HttpClient,
330 service_names: &'r [ServiceName],
331 endpoints_provider: E,
332 parts: RequestBuilderParts<'r>,
333 body: B,
334}
335
336impl<'r, B: Default + 'r, E: EndpointsProvider + 'r> RequestBuilder<'r, B, E> {
337 pub(in super::super) fn new(
338 http_client: &'r HttpClient,
339 method: Method,
340 endpoints_provider: E,
341 service_names: &'r [ServiceName],
342 ) -> Self {
343 Self {
344 http_client,
345 service_names,
346 endpoints_provider,
347 parts: RequestBuilderParts {
348 metadata: RequestMetadata {
349 method,
350 ..Default::default()
351 },
352 ..Default::default()
353 },
354 body: Default::default(),
355 }
356 }
357}
358
359impl<'r, B: 'r, E: 'r> RequestBuilder<'r, B, E> {
360 #[inline]
362 pub fn use_https(&mut self, use_https: bool) -> &mut Self {
363 self.parts.use_https(use_https);
364 self
365 }
366
367 #[inline]
369 pub fn version(&mut self, version: Version) -> &mut Self {
370 self.parts.version(version);
371 self
372 }
373
374 #[inline]
376 pub fn path(&mut self, path: impl Into<Cow<'r, str>>) -> &mut Self {
377 self.parts.path(path);
378 self
379 }
380
381 #[inline]
383 pub fn headers(&mut self, headers: impl Into<Cow<'r, HeaderMap>>) -> &mut Self {
384 self.parts.headers(headers);
385 self
386 }
387
388 #[inline]
390 pub fn set_header(&mut self, header_name: impl IntoHeaderName, header_value: impl Into<HeaderValue>) -> &mut Self {
391 self.parts.set_header(header_name, header_value);
392 self
393 }
394
395 #[inline]
397 pub fn accept_json(&mut self) -> &mut Self {
398 self.parts.accept_json();
399 self
400 }
401
402 #[inline]
404 pub fn accept_application_octet_stream(&mut self) -> &mut Self {
405 self.parts.accept_application_octet_stream();
406 self
407 }
408
409 #[inline]
411 pub fn query(&mut self, query: impl Into<Cow<'r, str>>) -> &mut Self {
412 self.parts.query(query);
413 self
414 }
415
416 #[inline]
418 pub fn query_pairs(&mut self, query_pairs: impl Into<Vec<QueryPair<'r>>>) -> &mut Self {
419 self.parts.query_pairs(query_pairs);
420 self
421 }
422
423 #[inline]
425 pub fn append_query_pair(
426 &mut self,
427 query_pair_key: impl Into<QueryPairKey<'r>>,
428 query_pair_value: impl Into<QueryPairValue<'r>>,
429 ) -> &mut Self {
430 self.parts.append_query_pair(query_pair_key, query_pair_value);
431 self
432 }
433
434 #[inline]
436 pub fn appended_user_agent(&mut self, user_agent: impl Into<UserAgent>) -> &mut Self {
437 self.parts.appended_user_agent(user_agent);
438 self
439 }
440
441 #[inline]
443 pub fn authorization(&mut self, authorization: Authorization<'r>) -> &mut Self {
444 self.parts.authorization(authorization);
445 self
446 }
447
448 #[inline]
450 pub fn idempotent(&mut self, idempotent: Idempotent) -> &mut Self {
451 self.parts.idempotent(idempotent);
452 self
453 }
454
455 #[inline]
457 pub fn extensions(&mut self, extensions: Extensions) -> &mut Self {
458 self.parts.extensions(extensions);
459 self
460 }
461
462 #[inline]
464 pub fn add_extension<T: Send + Sync + 'static>(&mut self, val: T) -> &mut Self {
465 self.parts.add_extension(val);
466 self
467 }
468
469 #[inline]
471 pub fn on_uploading_progress(
472 &mut self,
473 callback: impl Fn(&dyn SimplifiedCallbackContext, TransferProgressInfo<'_>) -> AnyResult<()> + Send + Sync + 'r,
474 ) -> &mut Self {
475 self.parts.on_uploading_progress(callback);
476 self
477 }
478
479 #[inline]
481 pub fn on_receive_response_status(
482 &mut self,
483 callback: impl Fn(&dyn SimplifiedCallbackContext, StatusCode) -> AnyResult<()> + Send + Sync + 'r,
484 ) -> &mut Self {
485 self.parts.on_receive_response_status(callback);
486 self
487 }
488
489 #[inline]
491 pub fn on_receive_response_header(
492 &mut self,
493 callback: impl Fn(&dyn SimplifiedCallbackContext, &HeaderName, &HeaderValue) -> AnyResult<()> + Send + Sync + 'r,
494 ) -> &mut Self {
495 self.parts.on_receive_response_header(callback);
496 self
497 }
498
499 #[inline]
501 pub fn on_to_resolve_domain(
502 &mut self,
503 callback: impl Fn(&mut dyn CallbackContext, &str) -> AnyResult<()> + Send + Sync + 'r,
504 ) -> &mut Self {
505 self.parts.on_to_resolve_domain(callback);
506 self
507 }
508
509 #[inline]
511 pub fn on_domain_resolved(
512 &mut self,
513 callback: impl Fn(&mut dyn CallbackContext, &str, &ResolveAnswers) -> AnyResult<()> + Send + Sync + 'r,
514 ) -> &mut Self {
515 self.parts.on_domain_resolved(callback);
516 self
517 }
518
519 #[inline]
521 pub fn on_to_choose_ips(
522 &mut self,
523 callback: impl Fn(&mut dyn CallbackContext, &[IpAddrWithPort]) -> AnyResult<()> + Send + Sync + 'r,
524 ) -> &mut Self {
525 self.parts.on_to_choose_ips(callback);
526 self
527 }
528
529 #[inline]
531 pub fn on_ips_chosen(
532 &mut self,
533 callback: impl Fn(&mut dyn CallbackContext, &[IpAddrWithPort], &[IpAddrWithPort]) -> AnyResult<()>
534 + Send
535 + Sync
536 + 'r,
537 ) -> &mut Self {
538 self.parts.on_ips_chosen(callback);
539 self
540 }
541
542 #[inline]
544 pub fn on_before_request_signed(
545 &mut self,
546 callback: impl Fn(&mut dyn ExtendedCallbackContext) -> AnyResult<()> + Send + Sync + 'r,
547 ) -> &mut Self {
548 self.parts.on_before_request_signed(callback);
549 self
550 }
551
552 #[inline]
554 pub fn on_after_request_signed(
555 &mut self,
556 callback: impl Fn(&mut dyn ExtendedCallbackContext) -> AnyResult<()> + Send + Sync + 'r,
557 ) -> &mut Self {
558 self.parts.on_after_request_signed(callback);
559 self
560 }
561
562 #[inline]
564 pub fn on_response(
565 &mut self,
566 callback: impl Fn(&mut dyn ExtendedCallbackContext, &ResponseParts) -> AnyResult<()> + Send + Sync + 'r,
567 ) -> &mut Self {
568 self.parts.on_response(callback);
569 self
570 }
571
572 #[inline]
574 pub fn on_error(
575 &mut self,
576 callback: impl Fn(&mut dyn ExtendedCallbackContext, &mut ResponseError) -> AnyResult<()> + Send + Sync + 'r,
577 ) -> &mut Self {
578 self.parts.on_error(callback);
579 self
580 }
581
582 #[inline]
584 pub fn on_before_backoff(
585 &mut self,
586 callback: impl Fn(&mut dyn ExtendedCallbackContext, Duration) -> AnyResult<()> + Send + Sync + 'r,
587 ) -> &mut Self {
588 self.parts.on_before_backoff(callback);
589 self
590 }
591
592 #[inline]
594 pub fn on_after_backoff(
595 &mut self,
596 callback: impl Fn(&mut dyn ExtendedCallbackContext, Duration) -> AnyResult<()> + Send + Sync + 'r,
597 ) -> &mut Self {
598 self.parts.on_after_backoff(callback);
599 self
600 }
601
602 #[inline]
604 pub fn parts(&self) -> &RequestBuilderParts<'r> {
605 &self.parts
606 }
607
608 #[inline]
610 pub fn parts_mut(&mut self) -> &mut RequestBuilderParts<'r> {
611 &mut self.parts
612 }
613
614 #[inline]
616 pub fn into_parts(self) -> RequestBuilderParts<'r> {
617 self.parts
618 }
619
620 fn get_appended_user_agent(&self) -> UserAgent {
621 let mut appended_user_agent = self.http_client.appended_user_agent().to_owned();
622 appended_user_agent.push_str(self.parts.appended_user_agent.as_str());
623 appended_user_agent
624 }
625}
626
627impl<'r, B: Sync + Send + 'r, E: Sync + Send + 'r> RequestBuilder<'r, B, E> {
628 #[allow(dead_code)]
629 fn ignore() {
630 assert_impl!(Send: Self);
631 assert_impl!(Sync: Self);
632 }
633}
634
635pub type SyncRequestBuilder<'r, E> = RequestBuilder<'r, SyncRequestBody<'r>, E>;
637
638impl<'r, E: 'r> SyncRequestBuilder<'r, E> {
639 #[inline]
641 pub fn stream_as_body(
642 &mut self,
643 body: impl Read + Reset + Debug + Send + Sync + 'static,
644 content_length: u64,
645 content_type: Option<Mime>,
646 ) -> &mut Self {
647 self.body = SyncRequestBody::from_reader(body, content_length);
648 self.parts.set_content_type(content_type);
649 self
650 }
651
652 #[inline]
654 pub fn referenced_stream_as_body<T: Read + Reset + Debug + Send + Sync>(
655 &mut self,
656 body: &'r mut T,
657 content_length: u64,
658 content_type: Option<Mime>,
659 ) -> &mut Self {
660 self.body = SyncRequestBody::from_referenced_reader(body, content_length);
661 self.parts.set_content_type(content_type);
662 self
663 }
664
665 #[inline]
667 pub fn bytes_as_body(&mut self, body: impl Into<Vec<u8>>, content_type: Option<Mime>) -> &mut Self {
668 self.body = SyncRequestBody::from_bytes(body.into());
669 self.parts.set_content_type(content_type);
670 self
671 }
672
673 #[inline]
675 pub fn referenced_bytes_as_body(&mut self, body: &'r [u8], content_type: Option<Mime>) -> &mut Self {
676 self.body = SyncRequestBody::from_referenced_bytes(body);
677 self.parts.set_content_type(content_type);
678 self
679 }
680
681 #[inline]
683 pub fn json(&mut self, body: impl Serialize) -> JsonResult<&mut Self> {
684 Ok(self.bytes_as_body(serde_json::to_vec(&body)?, Some(APPLICATION_JSON)))
685 }
686
687 #[inline]
689 pub fn post_form<I, K, V>(&mut self, iter: I) -> &mut Self
690 where
691 I: IntoIterator,
692 I::Item: Borrow<(K, Option<V>)>,
693 K: AsRef<str>,
694 V: AsRef<str>,
695 {
696 let mut form = form_urlencoded::Serializer::new(String::new());
697 for pair in iter {
698 let (k, v) = pair.borrow();
699 if let Some(v) = v {
700 form.append_pair(k.as_ref(), v.as_ref());
701 } else {
702 form.append_key_only(k.as_ref());
703 }
704 }
705 self.bytes_as_body(form.finish().into_bytes(), Some(APPLICATION_WWW_FORM_URLENCODED))
706 }
707
708 #[inline]
710 pub fn multipart<'a>(&mut self, multipart: impl Into<SyncMultipart<'a>>) -> IoResult<&mut Self> {
711 let mut buf = Vec::new();
712 let multipart = multipart.into();
713 let mime = ("multipart/form-data; boundary=".to_owned() + multipart.boundary())
714 .parse()
715 .unwrap();
716 multipart.into_read().read_to_end(&mut buf)?;
717 Ok(self.bytes_as_body(buf, Some(mime)))
718 }
719}
720
721impl<'r, E: EndpointsProvider + Clone + 'r> SyncRequestBuilder<'r, E> {
722 #[inline]
724 pub fn call(&mut self) -> ApiResult<SyncResponse> {
725 request_call(self.build())
726 }
727
728 pub(in super::super) fn build(&mut self) -> SyncInnerRequest<'r, E> {
729 SyncInnerRequest::new(
730 self.http_client,
731 self.endpoints_provider.to_owned(),
732 self.service_names,
733 self.parts.callbacks.build(),
734 take(&mut self.parts.metadata),
735 take(&mut self.body),
736 self.get_appended_user_agent(),
737 take(&mut self.parts.extensions),
738 )
739 }
740}
741
742#[cfg(feature = "async")]
744pub type AsyncRequestBuilder<'r, E> = RequestBuilder<'r, AsyncRequestBody<'r>, E>;
745
746#[cfg(feature = "async")]
747impl<'r, E: 'r> AsyncRequestBuilder<'r, E> {
748 #[inline]
750 pub fn stream_as_body(
751 &mut self,
752 body: impl AsyncRead + AsyncReset + Unpin + Debug + Send + Sync + 'static,
753 content_length: u64,
754 content_type: Option<Mime>,
755 ) -> &mut Self {
756 self.body = AsyncRequestBody::from_reader(body, content_length);
757 self.parts.set_content_type(content_type);
758 self
759 }
760
761 #[inline]
763 pub fn referenced_stream_as_body<T: AsyncRead + AsyncReset + Unpin + Debug + Send + Sync>(
764 &mut self,
765 body: &'r mut T,
766 content_length: u64,
767 content_type: Option<Mime>,
768 ) -> &mut Self {
769 self.body = AsyncRequestBody::from_referenced_reader(body, content_length);
770 self.parts.set_content_type(content_type);
771 self
772 }
773
774 #[inline]
776 pub fn bytes_as_body(&mut self, body: impl Into<Vec<u8>>, content_type: Option<Mime>) -> &mut Self {
777 self.body = AsyncRequestBody::from_bytes(body.into());
778 self.parts.set_content_type(content_type);
779 self
780 }
781
782 #[inline]
784 pub fn referenced_bytes_as_body(&mut self, body: &'r [u8], content_type: Option<Mime>) -> &mut Self {
785 self.body = AsyncRequestBody::from_referenced_bytes(body);
786 self.parts.set_content_type(content_type);
787 self
788 }
789
790 #[inline]
792 pub fn json(&mut self, body: impl Serialize) -> JsonResult<&mut Self> {
793 Ok(self.bytes_as_body(serde_json::to_vec(&body)?, Some(APPLICATION_JSON)))
794 }
795
796 #[inline]
798 pub fn post_form<I, K, V>(&mut self, iter: I) -> &mut Self
799 where
800 I: IntoIterator,
801 I::Item: Borrow<(K, Option<V>)>,
802 K: AsRef<str>,
803 V: AsRef<str>,
804 {
805 let mut form = form_urlencoded::Serializer::new(String::new());
806 for pair in iter {
807 let (k, v) = pair.borrow();
808 if let Some(v) = v {
809 form.append_pair(k.as_ref(), v.as_ref());
810 } else {
811 form.append_key_only(k.as_ref());
812 }
813 }
814 self.bytes_as_body(form.finish().into_bytes(), Some(APPLICATION_WWW_FORM_URLENCODED))
815 }
816
817 #[inline]
819 pub async fn multipart<'a>(
820 &mut self,
821 multipart: impl Into<AsyncMultipart<'a>>,
822 ) -> IoResult<&mut RequestBuilder<'r, AsyncRequestBody<'r>, E>> {
823 use futures::AsyncReadExt;
824
825 let mut buf = Vec::new();
826 let multipart = multipart.into();
827 let mime = ("multipart/form-data; boundary=".to_owned() + multipart.boundary())
828 .parse()
829 .unwrap();
830 multipart.into_async_read().read_to_end(&mut buf).await?;
831 Ok(self.bytes_as_body(buf, Some(mime)))
832 }
833}
834
835#[cfg(feature = "async")]
836impl<'r, E: EndpointsProvider + Clone + 'r> AsyncRequestBuilder<'r, E> {
837 #[inline]
839 pub async fn call(&mut self) -> ApiResult<AsyncResponse> {
840 async_request_call(self.build()).await
841 }
842
843 pub(in super::super) fn build(&mut self) -> AsyncInnerRequest<'r, E> {
844 AsyncInnerRequest::new(
845 self.http_client,
846 self.endpoints_provider.to_owned(),
847 self.service_names,
848 self.parts.callbacks.build(),
849 take(&mut self.parts.metadata),
850 take(&mut self.body),
851 self.get_appended_user_agent(),
852 take(&mut self.parts.extensions),
853 )
854 }
855}
856
857#[derive(Default, Debug)]
861pub struct RequestParts<'r> {
862 metadata: RequestMetadata<'r>,
863 extensions: Extensions,
864 appended_user_agent: UserAgent,
865}
866
867impl CallbackContext for RequestParts<'_> {
868 #[inline]
869 fn extensions(&self) -> &Extensions {
870 &self.extensions
871 }
872
873 #[inline]
874 fn extensions_mut(&mut self) -> &mut Extensions {
875 &mut self.extensions
876 }
877}
878
879impl SimplifiedCallbackContext for RequestParts<'_> {
880 #[inline]
881 fn use_https(&self) -> bool {
882 self.metadata.use_https.unwrap_or(true)
883 }
884
885 #[inline]
886 fn method(&self) -> &Method {
887 &self.metadata.method
888 }
889
890 #[inline]
891 fn version(&self) -> Version {
892 self.metadata.version
893 }
894
895 #[inline]
896 fn path(&self) -> &str {
897 &self.metadata.path
898 }
899
900 #[inline]
901 fn query(&self) -> &str {
902 &self.metadata.query
903 }
904
905 #[inline]
906 fn query_pairs(&self) -> &[QueryPair] {
907 &self.metadata.query_pairs
908 }
909
910 #[inline]
911 fn headers(&self) -> &HeaderMap {
912 &self.metadata.headers
913 }
914
915 #[inline]
916 fn appended_user_agent(&self) -> &UserAgent {
917 &self.appended_user_agent
918 }
919
920 #[inline]
921 fn authorization(&self) -> Option<&Authorization> {
922 self.metadata.authorization.as_ref()
923 }
924
925 #[inline]
926 fn idempotent(&self) -> Idempotent {
927 self.metadata.idempotent
928 }
929}
930
931impl RequestParts<'_> {
932 #[allow(dead_code)]
933 fn ignore() {
934 assert_impl!(Send: Self);
935 assert_impl!(Sync: Self);
936 }
937}