1#![allow(dead_code)]
4
5use std::ops::{Deref, DerefMut};
8
9use bytes::Bytes;
10use futures_core::Stream;
11use reqwest::RequestBuilder;
12use serde::{Serialize, de::DeserializeOwned, ser::SerializeStruct};
13
14#[cfg(not(target_arch = "wasm32"))]
15type InnerByteStream = std::pin::Pin<Box<dyn Stream<Item = reqwest::Result<Bytes>> + Send + Sync>>;
16
17#[cfg(target_arch = "wasm32")]
18type InnerByteStream = std::pin::Pin<Box<dyn Stream<Item = reqwest::Result<Bytes>>>>;
19
20pub struct ByteStream(InnerByteStream);
22
23impl ByteStream {
24 pub fn new(inner: InnerByteStream) -> Self {
28 Self(inner)
29 }
30
31 pub fn into_inner(self) -> InnerByteStream {
33 self.0
34 }
35}
36
37impl Deref for ByteStream {
38 type Target = InnerByteStream;
39
40 fn deref(&self) -> &Self::Target {
41 &self.0
42 }
43}
44
45impl DerefMut for ByteStream {
46 fn deref_mut(&mut self) -> &mut Self::Target {
47 &mut self.0
48 }
49}
50
51pub trait ClientInfo<Inner> {
53 fn api_version() -> &'static str;
58
59 fn baseurl(&self) -> &str;
61
62 fn client(&self) -> &reqwest::Client;
64
65 fn inner(&self) -> &Inner;
67}
68
69impl<T, Inner> ClientInfo<Inner> for &T
70where
71 T: ClientInfo<Inner>,
72{
73 fn api_version() -> &'static str {
74 T::api_version()
75 }
76
77 fn baseurl(&self) -> &str {
78 (*self).baseurl()
79 }
80
81 fn client(&self) -> &reqwest::Client {
82 (*self).client()
83 }
84
85 fn inner(&self) -> &Inner {
86 (*self).inner()
87 }
88}
89
90pub struct OperationInfo {
92 pub operation_id: &'static str,
94}
95
96#[allow(async_fn_in_trait, unused)]
101pub trait ClientHooks<Inner = ()>
102where
103 Self: ClientInfo<Inner>,
104{
105 async fn pre<E>(
108 &self,
109 request: &mut reqwest::Request,
110 info: &OperationInfo,
111 ) -> std::result::Result<(), Error<E>> {
112 Ok(())
113 }
114
115 async fn post<E>(
117 &self,
118 result: &reqwest::Result<reqwest::Response>,
119 info: &OperationInfo,
120 ) -> std::result::Result<(), Error<E>> {
121 Ok(())
122 }
123
124 async fn exec(
146 &self,
147 request: reqwest::Request,
148 info: &OperationInfo,
149 ) -> reqwest::Result<reqwest::Response> {
150 self.client().execute(request).await
151 }
152}
153
154pub struct ResponseValue<T> {
159 inner: T,
160 status: reqwest::StatusCode,
161 headers: reqwest::header::HeaderMap,
162 }
164
165impl<T: DeserializeOwned> ResponseValue<T> {
166 #[doc(hidden)]
167 pub async fn from_response<E>(response: reqwest::Response) -> Result<Self, Error<E>> {
168 let status = response.status();
169 let headers = response.headers().clone();
170 let full = response.bytes().await.map_err(Error::ResponseBodyError)?;
171 let inner =
172 serde_json::from_slice(&full).map_err(|e| Error::InvalidResponsePayload(full, e))?;
173
174 Ok(Self {
175 inner,
176 status,
177 headers,
178 })
179 }
180}
181
182#[cfg(not(target_arch = "wasm32"))]
183impl ResponseValue<reqwest::Upgraded> {
184 #[doc(hidden)]
185 pub async fn upgrade<E: std::fmt::Debug>(
186 response: reqwest::Response,
187 ) -> Result<Self, Error<E>> {
188 let status = response.status();
189 let headers = response.headers().clone();
190 if status == reqwest::StatusCode::SWITCHING_PROTOCOLS {
191 let inner = response.upgrade().await.map_err(Error::InvalidUpgrade)?;
192
193 Ok(Self {
194 inner,
195 status,
196 headers,
197 })
198 } else {
199 Err(Error::UnexpectedResponse(response))
200 }
201 }
202}
203
204impl ResponseValue<ByteStream> {
205 #[doc(hidden)]
206 pub fn stream(response: reqwest::Response) -> Self {
207 let status = response.status();
208 let headers = response.headers().clone();
209 Self {
210 inner: ByteStream(Box::pin(response.bytes_stream())),
211 status,
212 headers,
213 }
214 }
215}
216
217impl ResponseValue<()> {
218 #[doc(hidden)]
219 pub fn empty(response: reqwest::Response) -> Self {
220 let status = response.status();
221 let headers = response.headers().clone();
222 Self {
225 inner: (),
226 status,
227 headers,
228 }
229 }
230}
231
232impl<T> ResponseValue<T> {
233 pub fn new(inner: T, status: reqwest::StatusCode, headers: reqwest::header::HeaderMap) -> Self {
237 Self {
238 inner,
239 status,
240 headers,
241 }
242 }
243
244 pub fn into_inner(self) -> T {
246 self.inner
247 }
248
249 pub fn status(&self) -> reqwest::StatusCode {
251 self.status
252 }
253
254 pub fn headers(&self) -> &reqwest::header::HeaderMap {
256 &self.headers
257 }
258
259 pub fn content_length(&self) -> Option<u64> {
262 self.headers
263 .get(reqwest::header::CONTENT_LENGTH)?
264 .to_str()
265 .ok()?
266 .parse::<u64>()
267 .ok()
268 }
269
270 #[doc(hidden)]
271 pub fn map<U: std::fmt::Debug, F, E>(self, f: F) -> Result<ResponseValue<U>, E>
272 where
273 F: FnOnce(T) -> U,
274 {
275 let Self {
276 inner,
277 status,
278 headers,
279 } = self;
280
281 Ok(ResponseValue {
282 inner: f(inner),
283 status,
284 headers,
285 })
286 }
287}
288
289impl ResponseValue<ByteStream> {
290 pub fn into_inner_stream(self) -> InnerByteStream {
292 self.into_inner().into_inner()
293 }
294}
295
296impl<T> Deref for ResponseValue<T> {
297 type Target = T;
298
299 fn deref(&self) -> &Self::Target {
300 &self.inner
301 }
302}
303
304impl<T> DerefMut for ResponseValue<T> {
305 fn deref_mut(&mut self) -> &mut Self::Target {
306 &mut self.inner
307 }
308}
309
310impl<T> AsRef<T> for ResponseValue<T> {
311 fn as_ref(&self) -> &T {
312 &self.inner
313 }
314}
315
316impl<T: std::fmt::Debug> std::fmt::Debug for ResponseValue<T> {
317 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
318 self.inner.fmt(f)
319 }
320}
321
322pub enum Error<E = ()> {
328 InvalidRequest(String),
330
331 CommunicationError(reqwest::Error),
333
334 InvalidUpgrade(reqwest::Error),
336
337 ErrorResponse(ResponseValue<E>),
339
340 ResponseBodyError(reqwest::Error),
342
343 InvalidResponsePayload(Bytes, serde_json::Error),
345
346 UnexpectedResponse(reqwest::Response),
349
350 Custom(String),
352}
353
354impl<E> Error<E> {
355 pub fn status(&self) -> Option<reqwest::StatusCode> {
357 match self {
358 Error::InvalidRequest(_) => None,
359 Error::Custom(_) => None,
360 Error::CommunicationError(e) => e.status(),
361 Error::ErrorResponse(rv) => Some(rv.status()),
362 Error::InvalidUpgrade(e) => e.status(),
363 Error::ResponseBodyError(e) => e.status(),
364 Error::InvalidResponsePayload(_, _) => None,
365 Error::UnexpectedResponse(r) => Some(r.status()),
366 }
367 }
368
369 pub fn is_retryable(&self) -> bool {
380 match self {
381 Error::CommunicationError(_) => true,
382 Error::ErrorResponse(rv) => is_retryable_status(rv.status()),
383 Error::UnexpectedResponse(r) => is_retryable_status(r.status()),
384 Error::InvalidUpgrade(e) | Error::ResponseBodyError(e) => {
385 e.status().is_some_and(is_retryable_status)
394 }
395 Error::InvalidRequest(_) => false,
396 Error::InvalidResponsePayload(_, _) => false,
397 Error::Custom(_) => false,
398 }
399 }
400
401 pub fn into_untyped(self) -> Error {
406 match self {
407 Error::InvalidRequest(s) => Error::InvalidRequest(s),
408 Error::Custom(s) => Error::Custom(s),
409 Error::CommunicationError(e) => Error::CommunicationError(e),
410 Error::ErrorResponse(ResponseValue {
411 inner: _,
412 status,
413 headers,
414 }) => Error::ErrorResponse(ResponseValue {
415 inner: (),
416 status,
417 headers,
418 }),
419 Error::InvalidUpgrade(e) => Error::InvalidUpgrade(e),
420 Error::ResponseBodyError(e) => Error::ResponseBodyError(e),
421 Error::InvalidResponsePayload(b, e) => Error::InvalidResponsePayload(b, e),
422 Error::UnexpectedResponse(r) => Error::UnexpectedResponse(r),
423 }
424 }
425}
426
427impl<E> From<std::convert::Infallible> for Error<E> {
428 fn from(x: std::convert::Infallible) -> Self {
429 match x {}
430 }
431}
432
433impl<E> From<reqwest::Error> for Error<E> {
434 fn from(e: reqwest::Error) -> Self {
435 Self::CommunicationError(e)
436 }
437}
438
439impl<E> From<reqwest::header::InvalidHeaderValue> for Error<E> {
440 fn from(e: reqwest::header::InvalidHeaderValue) -> Self {
441 Self::InvalidRequest(e.to_string())
442 }
443}
444
445impl<E> std::fmt::Display for Error<E>
446where
447 ResponseValue<E>: ErrorFormat,
448{
449 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
450 match self {
451 Error::InvalidRequest(s) => {
452 write!(f, "Invalid Request: {}", s)?;
453 }
454 Error::CommunicationError(e) => {
455 write!(f, "Communication Error: {}", e)?;
456 }
457 Error::ErrorResponse(rve) => {
458 write!(f, "Error Response: ")?;
459 rve.fmt_info(f)?;
460 }
461 Error::InvalidUpgrade(e) => {
462 write!(f, "Invalid Response Upgrade: {}", e)?;
463 }
464 Error::ResponseBodyError(e) => {
465 write!(f, "Invalid Response Body Bytes: {}", e)?;
466 }
467 Error::InvalidResponsePayload(b, e) => {
468 write!(f, "Invalid Response Payload ({:?}): {}", b, e)?;
469 }
470 Error::UnexpectedResponse(r) => {
471 write!(f, "Unexpected Response: {:?}", r)?;
472 }
473 Error::Custom(s) => {
474 write!(f, "Error: {}", s)?;
475 }
476 }
477
478 if f.alternate() {
479 use std::error::Error as _;
480
481 let mut src = self.source().and_then(|e| e.source());
482 while let Some(s) = src {
483 write!(f, ": {s}")?;
484 src = s.source();
485 }
486 }
487 Ok(())
488 }
489}
490
491trait ErrorFormat {
492 fn fmt_info(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
493}
494
495impl<E> ErrorFormat for ResponseValue<E>
496where
497 E: std::fmt::Debug,
498{
499 fn fmt_info(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
500 write!(
501 f,
502 "status: {}; headers: {:?}; value: {:?}",
503 self.status, self.headers, self.inner,
504 )
505 }
506}
507
508impl ErrorFormat for ResponseValue<ByteStream> {
509 fn fmt_info(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
510 write!(
511 f,
512 "status: {}; headers: {:?}; value: <stream>",
513 self.status, self.headers,
514 )
515 }
516}
517
518impl<E> std::fmt::Debug for Error<E>
519where
520 ResponseValue<E>: ErrorFormat,
521{
522 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
523 std::fmt::Display::fmt(self, f)
524 }
525}
526impl<E> std::error::Error for Error<E>
527where
528 ResponseValue<E>: ErrorFormat,
529{
530 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
531 match self {
532 Error::CommunicationError(e) => Some(e),
533 Error::InvalidUpgrade(e) => Some(e),
534 Error::ResponseBodyError(e) => Some(e),
535 Error::InvalidResponsePayload(_b, e) => Some(e),
536 _ => None,
537 }
538 }
539}
540
541fn is_retryable_status(status: reqwest::StatusCode) -> bool {
544 matches!(
545 status,
546 reqwest::StatusCode::TOO_MANY_REQUESTS
547 | reqwest::StatusCode::BAD_GATEWAY
548 | reqwest::StatusCode::SERVICE_UNAVAILABLE
549 | reqwest::StatusCode::GATEWAY_TIMEOUT
550 )
551}
552
553const PATH_SET: &percent_encoding::AsciiSet = &percent_encoding::CONTROLS
555 .add(b' ')
556 .add(b'"')
557 .add(b'#')
558 .add(b'<')
559 .add(b'>')
560 .add(b'?')
561 .add(b'`')
562 .add(b'{')
563 .add(b'}')
564 .add(b'/')
565 .add(b'%');
566
567#[doc(hidden)]
568pub fn encode_path(pc: &str) -> String {
570 percent_encoding::utf8_percent_encode(pc, PATH_SET).to_string()
571}
572
573#[doc(hidden)]
574pub trait RequestBuilderExt<E> {
575 fn form_urlencoded<T: Serialize + ?Sized>(self, body: &T) -> Result<RequestBuilder, Error<E>>;
576}
577
578impl<E> RequestBuilderExt<E> for RequestBuilder {
579 fn form_urlencoded<T: Serialize + ?Sized>(self, body: &T) -> Result<Self, Error<E>> {
580 Ok(self
581 .header(
582 reqwest::header::CONTENT_TYPE,
583 reqwest::header::HeaderValue::from_static("application/x-www-form-urlencoded"),
584 )
585 .body(
586 serde_urlencoded::to_string(body)
587 .map_err(|_| Error::InvalidRequest("failed to serialize body".to_string()))?,
588 ))
589 }
590}
591
592#[doc(hidden)]
593pub struct QueryParam<'a, T> {
594 name: &'a str,
595 value: &'a T,
596}
597
598impl<'a, T> QueryParam<'a, T> {
599 #[doc(hidden)]
600 pub fn new(name: &'a str, value: &'a T) -> Self {
601 Self { name, value }
602 }
603}
604impl<T> Serialize for QueryParam<'_, T>
605where
606 T: Serialize,
607{
608 fn serialize<S>(&self, inner: S) -> Result<S::Ok, S::Error>
609 where
610 S: serde::Serializer,
611 {
612 let serializer = QuerySerializer {
613 inner,
614 name: self.name,
615 };
616 self.value.serialize(serializer)
617 }
618}
619
620pub(crate) struct QuerySerializer<'a, S> {
621 inner: S,
622 name: &'a str,
623}
624
625macro_rules! serialize_scalar {
626 ($f:ident, $t:ty) => {
627 fn $f(self, v: $t) -> Result<Self::Ok, Self::Error> {
628 [(self.name, v)].serialize(self.inner)
629 }
630 };
631}
632
633impl<'a, S> serde::Serializer for QuerySerializer<'a, S>
634where
635 S: serde::Serializer,
636{
637 type Ok = S::Ok;
638 type Error = S::Error;
639 type SerializeSeq = QuerySeq<'a, S::SerializeSeq>;
640 type SerializeTuple = S::SerializeTuple;
641 type SerializeTupleStruct = S::SerializeTupleStruct;
642 type SerializeTupleVariant = S::SerializeTupleVariant;
643 type SerializeMap = S::SerializeMap;
644 type SerializeStruct = S::SerializeStruct;
645 type SerializeStructVariant = S::SerializeStructVariant;
646
647 serialize_scalar!(serialize_bool, bool);
648 serialize_scalar!(serialize_i8, i8);
649 serialize_scalar!(serialize_i16, i16);
650 serialize_scalar!(serialize_i32, i32);
651 serialize_scalar!(serialize_i64, i64);
652 serialize_scalar!(serialize_u8, u8);
653 serialize_scalar!(serialize_u16, u16);
654 serialize_scalar!(serialize_u32, u32);
655 serialize_scalar!(serialize_u64, u64);
656 serialize_scalar!(serialize_f32, f32);
657 serialize_scalar!(serialize_f64, f64);
658 serialize_scalar!(serialize_char, char);
659 serialize_scalar!(serialize_str, &str);
660
661 fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
662 self.inner.serialize_bytes(v)
663 }
664
665 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
666 self.inner.serialize_none()
667 }
668
669 fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
670 where
671 T: ?Sized + Serialize,
672 {
673 value.serialize(self)
676 }
677
678 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
679 self.inner.serialize_unit()
680 }
681
682 fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
683 self.inner.serialize_unit_struct(name)
684 }
685
686 fn serialize_unit_variant(
687 self,
688 _name: &'static str,
689 _variant_index: u32,
690 variant: &'static str,
691 ) -> Result<Self::Ok, Self::Error> {
692 variant.serialize(self)
696 }
697
698 fn serialize_newtype_struct<T>(
699 self,
700 name: &'static str,
701 value: &T,
702 ) -> Result<Self::Ok, Self::Error>
703 where
704 T: ?Sized + Serialize,
705 {
706 self.inner.serialize_newtype_struct(name, value)
707 }
708
709 fn serialize_newtype_variant<T>(
710 self,
711 name: &'static str,
712 _variant_index: u32,
713 variant: &'static str,
714 value: &T,
715 ) -> Result<Self::Ok, Self::Error>
716 where
717 T: ?Sized + Serialize,
718 {
719 let mut map = self.inner.serialize_struct(name, 1)?;
725 map.serialize_field(variant, value)?;
726 map.end()
727 }
728
729 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
730 let Self { inner, name, .. } = self;
731 Ok(QuerySeq {
732 inner: inner.serialize_seq(len)?,
733 name,
734 })
735 }
736
737 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
738 self.inner.serialize_tuple(len)
739 }
740
741 fn serialize_tuple_struct(
742 self,
743 name: &'static str,
744 len: usize,
745 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
746 self.inner.serialize_tuple_struct(name, len)
747 }
748
749 fn serialize_tuple_variant(
750 self,
751 name: &'static str,
752 variant_index: u32,
753 variant: &'static str,
754 len: usize,
755 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
756 self.inner
757 .serialize_tuple_variant(name, variant_index, variant, len)
758 }
759
760 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
761 self.inner.serialize_map(len)
762 }
763
764 fn serialize_struct(
765 self,
766 name: &'static str,
767 len: usize,
768 ) -> Result<Self::SerializeStruct, Self::Error> {
769 self.inner.serialize_struct(name, len)
770 }
771
772 fn serialize_struct_variant(
773 self,
774 name: &'static str,
775 variant_index: u32,
776 variant: &'static str,
777 len: usize,
778 ) -> Result<Self::SerializeStructVariant, Self::Error> {
779 self.inner
780 .serialize_struct_variant(name, variant_index, variant, len)
781 }
782}
783
784#[doc(hidden)]
785pub struct QuerySeq<'a, S> {
786 inner: S,
787 name: &'a str,
788}
789
790impl<S> serde::ser::SerializeSeq for QuerySeq<'_, S>
791where
792 S: serde::ser::SerializeSeq,
793{
794 type Ok = S::Ok;
795
796 type Error = S::Error;
797
798 fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
799 where
800 T: ?Sized + Serialize,
801 {
802 let v = (self.name, value);
803 self.inner.serialize_element(&v)
804 }
805
806 fn end(self) -> Result<Self::Ok, Self::Error> {
807 self.inner.end()
808 }
809}