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)]
101#[diagnostic::on_unimplemented(
102 message = "`{Self}` does not implement `ClientHooks<{Inner}>`",
103 label = "missing `impl ClientHooks<{Inner}> for {Self}`",
104 note = "clients generated with `hooks = Expected` require `impl ClientHooks<{Inner}> for {Self}`"
105)]
106pub trait ClientHooks<Inner = ()>
107where
108 Self: ClientInfo<Inner>,
109{
110 async fn pre<E>(
113 &self,
114 request: &mut reqwest::Request,
115 info: &OperationInfo,
116 ) -> std::result::Result<(), Error<E>> {
117 Ok(())
118 }
119
120 async fn post<E>(
122 &self,
123 result: &reqwest::Result<reqwest::Response>,
124 info: &OperationInfo,
125 ) -> std::result::Result<(), Error<E>> {
126 Ok(())
127 }
128
129 async fn exec(
151 &self,
152 request: reqwest::Request,
153 info: &OperationInfo,
154 ) -> reqwest::Result<reqwest::Response> {
155 self.client().execute(request).await
156 }
157}
158
159pub struct ResponseValue<T> {
164 inner: T,
165 status: reqwest::StatusCode,
166 headers: reqwest::header::HeaderMap,
167 }
169
170impl<T: DeserializeOwned> ResponseValue<T> {
171 #[doc(hidden)]
172 pub async fn from_response<E>(response: reqwest::Response) -> Result<Self, Error<E>> {
173 let status = response.status();
174 let headers = response.headers().clone();
175 let full = response.bytes().await.map_err(Error::ResponseBodyError)?;
176 let inner =
177 serde_json::from_slice(&full).map_err(|e| Error::InvalidResponsePayload(full, e))?;
178
179 Ok(Self {
180 inner,
181 status,
182 headers,
183 })
184 }
185}
186
187#[cfg(not(target_arch = "wasm32"))]
188impl ResponseValue<reqwest::Upgraded> {
189 #[doc(hidden)]
190 pub async fn upgrade<E: std::fmt::Debug>(
191 response: reqwest::Response,
192 ) -> Result<Self, Error<E>> {
193 let status = response.status();
194 let headers = response.headers().clone();
195 if status == reqwest::StatusCode::SWITCHING_PROTOCOLS {
196 let inner = response.upgrade().await.map_err(Error::InvalidUpgrade)?;
197
198 Ok(Self {
199 inner,
200 status,
201 headers,
202 })
203 } else {
204 Err(Error::UnexpectedResponse(response))
205 }
206 }
207}
208
209impl ResponseValue<ByteStream> {
210 #[doc(hidden)]
211 pub fn stream(response: reqwest::Response) -> Self {
212 let status = response.status();
213 let headers = response.headers().clone();
214 Self {
215 inner: ByteStream(Box::pin(response.bytes_stream())),
216 status,
217 headers,
218 }
219 }
220}
221
222impl ResponseValue<()> {
223 #[doc(hidden)]
224 pub fn empty(response: reqwest::Response) -> Self {
225 let status = response.status();
226 let headers = response.headers().clone();
227 Self {
230 inner: (),
231 status,
232 headers,
233 }
234 }
235}
236
237impl<T> ResponseValue<T> {
238 pub fn new(inner: T, status: reqwest::StatusCode, headers: reqwest::header::HeaderMap) -> Self {
242 Self {
243 inner,
244 status,
245 headers,
246 }
247 }
248
249 pub fn into_inner(self) -> T {
251 self.inner
252 }
253
254 pub fn status(&self) -> reqwest::StatusCode {
256 self.status
257 }
258
259 pub fn headers(&self) -> &reqwest::header::HeaderMap {
261 &self.headers
262 }
263
264 pub fn content_length(&self) -> Option<u64> {
267 self.headers
268 .get(reqwest::header::CONTENT_LENGTH)?
269 .to_str()
270 .ok()?
271 .parse::<u64>()
272 .ok()
273 }
274
275 #[doc(hidden)]
276 pub fn map<U: std::fmt::Debug, F, E>(self, f: F) -> Result<ResponseValue<U>, E>
277 where
278 F: FnOnce(T) -> U,
279 {
280 let Self {
281 inner,
282 status,
283 headers,
284 } = self;
285
286 Ok(ResponseValue {
287 inner: f(inner),
288 status,
289 headers,
290 })
291 }
292}
293
294impl ResponseValue<ByteStream> {
295 pub fn into_inner_stream(self) -> InnerByteStream {
297 self.into_inner().into_inner()
298 }
299}
300
301impl<T> Deref for ResponseValue<T> {
302 type Target = T;
303
304 fn deref(&self) -> &Self::Target {
305 &self.inner
306 }
307}
308
309impl<T> DerefMut for ResponseValue<T> {
310 fn deref_mut(&mut self) -> &mut Self::Target {
311 &mut self.inner
312 }
313}
314
315impl<T> AsRef<T> for ResponseValue<T> {
316 fn as_ref(&self) -> &T {
317 &self.inner
318 }
319}
320
321impl<T: std::fmt::Debug> std::fmt::Debug for ResponseValue<T> {
322 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
323 self.inner.fmt(f)
324 }
325}
326
327pub enum Error<E = ()> {
333 InvalidRequest(String),
335
336 CommunicationError(reqwest::Error),
338
339 InvalidUpgrade(reqwest::Error),
341
342 ErrorResponse(ResponseValue<E>),
344
345 ResponseBodyError(reqwest::Error),
347
348 InvalidResponsePayload(Bytes, serde_json::Error),
350
351 UnexpectedResponse(reqwest::Response),
354
355 Custom(String),
357}
358
359impl<E> Error<E> {
360 pub fn status(&self) -> Option<reqwest::StatusCode> {
362 match self {
363 Error::InvalidRequest(_) => None,
364 Error::Custom(_) => None,
365 Error::CommunicationError(e) => e.status(),
366 Error::ErrorResponse(rv) => Some(rv.status()),
367 Error::InvalidUpgrade(e) => e.status(),
368 Error::ResponseBodyError(e) => e.status(),
369 Error::InvalidResponsePayload(_, _) => None,
370 Error::UnexpectedResponse(r) => Some(r.status()),
371 }
372 }
373
374 pub fn is_retryable(&self) -> bool {
386 match self {
387 Error::CommunicationError(_) => true,
388 Error::ErrorResponse(rv) => is_retryable_status(rv.status()),
389 Error::UnexpectedResponse(r) => is_retryable_status(r.status()),
390 Error::InvalidUpgrade(e) | Error::ResponseBodyError(e) => {
391 e.status().is_some_and(is_retryable_status)
400 }
401 Error::InvalidRequest(_) => false,
402 Error::InvalidResponsePayload(_, _) => false,
403 Error::Custom(_) => false,
404 }
405 }
406
407 pub fn into_untyped(self) -> Error {
412 match self {
413 Error::InvalidRequest(s) => Error::InvalidRequest(s),
414 Error::Custom(s) => Error::Custom(s),
415 Error::CommunicationError(e) => Error::CommunicationError(e),
416 Error::ErrorResponse(ResponseValue {
417 inner: _,
418 status,
419 headers,
420 }) => Error::ErrorResponse(ResponseValue {
421 inner: (),
422 status,
423 headers,
424 }),
425 Error::InvalidUpgrade(e) => Error::InvalidUpgrade(e),
426 Error::ResponseBodyError(e) => Error::ResponseBodyError(e),
427 Error::InvalidResponsePayload(b, e) => Error::InvalidResponsePayload(b, e),
428 Error::UnexpectedResponse(r) => Error::UnexpectedResponse(r),
429 }
430 }
431}
432
433impl<E> From<std::convert::Infallible> for Error<E> {
434 fn from(x: std::convert::Infallible) -> Self {
435 match x {}
436 }
437}
438
439impl<E> From<reqwest::Error> for Error<E> {
440 fn from(e: reqwest::Error) -> Self {
441 Self::CommunicationError(e)
442 }
443}
444
445impl<E> From<reqwest::header::InvalidHeaderValue> for Error<E> {
446 fn from(e: reqwest::header::InvalidHeaderValue) -> Self {
447 Self::InvalidRequest(e.to_string())
448 }
449}
450
451impl<E> std::fmt::Display for Error<E>
452where
453 ResponseValue<E>: ErrorFormat,
454{
455 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
456 match self {
457 Error::InvalidRequest(s) => {
458 write!(f, "Invalid Request: {}", s)?;
459 }
460 Error::CommunicationError(e) => {
461 write!(f, "Communication Error: {}", e)?;
462 }
463 Error::ErrorResponse(rve) => {
464 write!(f, "Error Response: ")?;
465 rve.fmt_info(f)?;
466 }
467 Error::InvalidUpgrade(e) => {
468 write!(f, "Invalid Response Upgrade: {}", e)?;
469 }
470 Error::ResponseBodyError(e) => {
471 write!(f, "Invalid Response Body Bytes: {}", e)?;
472 }
473 Error::InvalidResponsePayload(b, e) => {
474 write!(f, "Invalid Response Payload ({:?}): {}", b, e)?;
475 }
476 Error::UnexpectedResponse(r) => {
477 write!(f, "Unexpected Response: {:?}", r)?;
478 }
479 Error::Custom(s) => {
480 write!(f, "Error: {}", s)?;
481 }
482 }
483
484 if f.alternate() {
485 use std::error::Error as _;
486
487 let mut src = self.source().and_then(|e| e.source());
488 while let Some(s) = src {
489 write!(f, ": {s}")?;
490 src = s.source();
491 }
492 }
493 Ok(())
494 }
495}
496
497trait ErrorFormat {
498 fn fmt_info(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
499}
500
501impl<E> ErrorFormat for ResponseValue<E>
502where
503 E: std::fmt::Debug,
504{
505 fn fmt_info(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
506 write!(
507 f,
508 "status: {}; headers: {:?}; value: {:?}",
509 self.status, self.headers, self.inner,
510 )
511 }
512}
513
514impl ErrorFormat for ResponseValue<ByteStream> {
515 fn fmt_info(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
516 write!(
517 f,
518 "status: {}; headers: {:?}; value: <stream>",
519 self.status, self.headers,
520 )
521 }
522}
523
524impl<E> std::fmt::Debug for Error<E>
525where
526 ResponseValue<E>: ErrorFormat,
527{
528 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
529 std::fmt::Display::fmt(self, f)
530 }
531}
532impl<E> std::error::Error for Error<E>
533where
534 ResponseValue<E>: ErrorFormat,
535{
536 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
537 match self {
538 Error::CommunicationError(e) => Some(e),
539 Error::InvalidUpgrade(e) => Some(e),
540 Error::ResponseBodyError(e) => Some(e),
541 Error::InvalidResponsePayload(_b, e) => Some(e),
542 _ => None,
543 }
544 }
545}
546
547fn is_retryable_status(status: reqwest::StatusCode) -> bool {
550 matches!(
551 status,
552 reqwest::StatusCode::REQUEST_TIMEOUT
553 | reqwest::StatusCode::TOO_MANY_REQUESTS
554 | reqwest::StatusCode::BAD_GATEWAY
555 | reqwest::StatusCode::SERVICE_UNAVAILABLE
556 | reqwest::StatusCode::GATEWAY_TIMEOUT
557 )
558}
559
560const PATH_SET: &percent_encoding::AsciiSet = &percent_encoding::CONTROLS
562 .add(b' ')
563 .add(b'"')
564 .add(b'#')
565 .add(b'<')
566 .add(b'>')
567 .add(b'?')
568 .add(b'`')
569 .add(b'{')
570 .add(b'}')
571 .add(b'/')
572 .add(b'%');
573
574#[doc(hidden)]
575pub fn encode_path(pc: &str) -> String {
577 percent_encoding::utf8_percent_encode(pc, PATH_SET).to_string()
578}
579
580#[doc(hidden)]
581pub trait RequestBuilderExt<E> {
582 fn form_urlencoded<T: Serialize + ?Sized>(self, body: &T) -> Result<RequestBuilder, Error<E>>;
583}
584
585impl<E> RequestBuilderExt<E> for RequestBuilder {
586 fn form_urlencoded<T: Serialize + ?Sized>(self, body: &T) -> Result<Self, Error<E>> {
587 Ok(self
588 .header(
589 reqwest::header::CONTENT_TYPE,
590 reqwest::header::HeaderValue::from_static("application/x-www-form-urlencoded"),
591 )
592 .body(
593 serde_urlencoded::to_string(body)
594 .map_err(|_| Error::InvalidRequest("failed to serialize body".to_string()))?,
595 ))
596 }
597}
598
599#[doc(hidden)]
600pub struct QueryParam<'a, T> {
601 name: &'a str,
602 value: &'a T,
603}
604
605impl<'a, T> QueryParam<'a, T> {
606 #[doc(hidden)]
607 pub fn new(name: &'a str, value: &'a T) -> Self {
608 Self { name, value }
609 }
610}
611impl<T> Serialize for QueryParam<'_, T>
612where
613 T: Serialize,
614{
615 fn serialize<S>(&self, inner: S) -> Result<S::Ok, S::Error>
616 where
617 S: serde::Serializer,
618 {
619 let serializer = QuerySerializer {
620 inner,
621 name: self.name,
622 };
623 self.value.serialize(serializer)
624 }
625}
626
627pub(crate) struct QuerySerializer<'a, S> {
628 inner: S,
629 name: &'a str,
630}
631
632macro_rules! serialize_scalar {
633 ($f:ident, $t:ty) => {
634 fn $f(self, v: $t) -> Result<Self::Ok, Self::Error> {
635 [(self.name, v)].serialize(self.inner)
636 }
637 };
638}
639
640impl<'a, S> serde::Serializer for QuerySerializer<'a, S>
641where
642 S: serde::Serializer,
643{
644 type Ok = S::Ok;
645 type Error = S::Error;
646 type SerializeSeq = QuerySeq<'a, S::SerializeSeq>;
647 type SerializeTuple = S::SerializeTuple;
648 type SerializeTupleStruct = S::SerializeTupleStruct;
649 type SerializeTupleVariant = S::SerializeTupleVariant;
650 type SerializeMap = S::SerializeMap;
651 type SerializeStruct = S::SerializeStruct;
652 type SerializeStructVariant = S::SerializeStructVariant;
653
654 serialize_scalar!(serialize_bool, bool);
655 serialize_scalar!(serialize_i8, i8);
656 serialize_scalar!(serialize_i16, i16);
657 serialize_scalar!(serialize_i32, i32);
658 serialize_scalar!(serialize_i64, i64);
659 serialize_scalar!(serialize_u8, u8);
660 serialize_scalar!(serialize_u16, u16);
661 serialize_scalar!(serialize_u32, u32);
662 serialize_scalar!(serialize_u64, u64);
663 serialize_scalar!(serialize_f32, f32);
664 serialize_scalar!(serialize_f64, f64);
665 serialize_scalar!(serialize_char, char);
666 serialize_scalar!(serialize_str, &str);
667
668 fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
669 self.inner.serialize_bytes(v)
670 }
671
672 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
673 self.inner.serialize_none()
674 }
675
676 fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
677 where
678 T: ?Sized + Serialize,
679 {
680 value.serialize(self)
683 }
684
685 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
686 self.inner.serialize_unit()
687 }
688
689 fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
690 self.inner.serialize_unit_struct(name)
691 }
692
693 fn serialize_unit_variant(
694 self,
695 _name: &'static str,
696 _variant_index: u32,
697 variant: &'static str,
698 ) -> Result<Self::Ok, Self::Error> {
699 variant.serialize(self)
703 }
704
705 fn serialize_newtype_struct<T>(
706 self,
707 name: &'static str,
708 value: &T,
709 ) -> Result<Self::Ok, Self::Error>
710 where
711 T: ?Sized + Serialize,
712 {
713 self.inner.serialize_newtype_struct(name, value)
714 }
715
716 fn serialize_newtype_variant<T>(
717 self,
718 name: &'static str,
719 _variant_index: u32,
720 variant: &'static str,
721 value: &T,
722 ) -> Result<Self::Ok, Self::Error>
723 where
724 T: ?Sized + Serialize,
725 {
726 let mut map = self.inner.serialize_struct(name, 1)?;
732 map.serialize_field(variant, value)?;
733 map.end()
734 }
735
736 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
737 let Self { inner, name, .. } = self;
738 Ok(QuerySeq {
739 inner: inner.serialize_seq(len)?,
740 name,
741 })
742 }
743
744 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
745 self.inner.serialize_tuple(len)
746 }
747
748 fn serialize_tuple_struct(
749 self,
750 name: &'static str,
751 len: usize,
752 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
753 self.inner.serialize_tuple_struct(name, len)
754 }
755
756 fn serialize_tuple_variant(
757 self,
758 name: &'static str,
759 variant_index: u32,
760 variant: &'static str,
761 len: usize,
762 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
763 self.inner
764 .serialize_tuple_variant(name, variant_index, variant, len)
765 }
766
767 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
768 self.inner.serialize_map(len)
769 }
770
771 fn serialize_struct(
772 self,
773 name: &'static str,
774 len: usize,
775 ) -> Result<Self::SerializeStruct, Self::Error> {
776 self.inner.serialize_struct(name, len)
777 }
778
779 fn serialize_struct_variant(
780 self,
781 name: &'static str,
782 variant_index: u32,
783 variant: &'static str,
784 len: usize,
785 ) -> Result<Self::SerializeStructVariant, Self::Error> {
786 self.inner
787 .serialize_struct_variant(name, variant_index, variant, len)
788 }
789}
790
791#[doc(hidden)]
792pub struct QuerySeq<'a, S> {
793 inner: S,
794 name: &'a str,
795}
796
797impl<S> serde::ser::SerializeSeq for QuerySeq<'_, S>
798where
799 S: serde::ser::SerializeSeq,
800{
801 type Ok = S::Ok;
802
803 type Error = S::Error;
804
805 fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
806 where
807 T: ?Sized + Serialize,
808 {
809 let v = (self.name, value);
810 self.inner.serialize_element(&v)
811 }
812
813 fn end(self) -> Result<Self::Ok, Self::Error> {
814 self.inner.end()
815 }
816}