1#![allow(dead_code)]
4
5use std::ops::{Deref, DerefMut};
8
9use bytes::Bytes;
10use futures_core::Stream;
11use reqwest::RequestBuilder;
12use serde::{de::DeserializeOwned, ser::SerializeStruct, Serialize};
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 cfg_if::cfg_if! {
63 if #[cfg(feature = "middleware")] {
64 fn client(&self) -> &reqwest_middleware::ClientWithMiddleware;
66 } else {
67 fn client(&self) -> &reqwest::Client;
69 }
70 }
71
72 fn inner(&self) -> &Inner;
74}
75
76impl<T, Inner> ClientInfo<Inner> for &T
77where
78 T: ClientInfo<Inner>,
79{
80 fn api_version() -> &'static str {
81 T::api_version()
82 }
83
84 fn baseurl(&self) -> &str {
85 (*self).baseurl()
86 }
87
88 cfg_if::cfg_if! {
89 if #[cfg(feature = "middleware")] {
90 fn client(&self) -> &reqwest_middleware::ClientWithMiddleware {
91 (*self).client()
92 }
93 } else {
94 fn client(&self) -> &reqwest::Client {
95 (*self).client()
96 }
97 }
98 }
99
100 fn inner(&self) -> &Inner {
101 (*self).inner()
102 }
103}
104
105pub struct OperationInfo {
107 pub operation_id: &'static str,
109}
110
111#[allow(async_fn_in_trait, unused)]
116pub trait ClientHooks<Inner = ()>
117where
118 Self: ClientInfo<Inner>,
119{
120 async fn pre<E>(
123 &self,
124 request: &mut reqwest::Request,
125 info: &OperationInfo,
126 ) -> std::result::Result<(), Error<E>> {
127 Ok(())
128 }
129
130 async fn post<E>(
132 &self,
133 result: &reqwest::Result<reqwest::Response>,
134 info: &OperationInfo,
135 ) -> std::result::Result<(), Error<E>> {
136 Ok(())
137 }
138
139 async fn exec(
141 &self,
142 request: reqwest::Request,
143 info: &OperationInfo,
144 ) -> reqwest::Result<reqwest::Response> {
145 cfg_if::cfg_if! {
146 if #[cfg(feature = "middleware")] {
147 match self.client().execute(request).await {
148 Ok(response) => Ok(response),
149 Err(reqwest_middleware::Error::Reqwest(req_err)) => Err(req_err),
150 Err(reqwest_middleware::Error::Middleware(_err)) => {
152 let client = reqwest::Client::new();
154 match client.get("http://127.0.0.1:0").send().await {
155 Err(e) => Err(e),
156 Ok(_) => unreachable!(),
157 }
158 }
159 }
160 } else {
161 self.client().execute(request).await
162 }
163 }
164 }
165}
166
167pub struct ResponseValue<T> {
172 inner: T,
173 status: reqwest::StatusCode,
174 headers: reqwest::header::HeaderMap,
175 }
177
178impl<T: DeserializeOwned> ResponseValue<T> {
179 #[doc(hidden)]
180 pub async fn from_response<E>(response: reqwest::Response) -> Result<Self, Error<E>> {
181 let status = response.status();
182 let headers = response.headers().clone();
183 let full = response.bytes().await.map_err(Error::ResponseBodyError)?;
184 let inner =
185 serde_json::from_slice(&full).map_err(|e| Error::InvalidResponsePayload(full, e))?;
186
187 Ok(Self {
188 inner,
189 status,
190 headers,
191 })
192 }
193}
194
195#[cfg(not(target_arch = "wasm32"))]
196impl ResponseValue<reqwest::Upgraded> {
197 #[doc(hidden)]
198 pub async fn upgrade<E: std::fmt::Debug>(
199 response: reqwest::Response,
200 ) -> Result<Self, Error<E>> {
201 let status = response.status();
202 let headers = response.headers().clone();
203 if status == reqwest::StatusCode::SWITCHING_PROTOCOLS {
204 let inner = response.upgrade().await.map_err(Error::InvalidUpgrade)?;
205
206 Ok(Self {
207 inner,
208 status,
209 headers,
210 })
211 } else {
212 Err(Error::UnexpectedResponse(response))
213 }
214 }
215}
216
217impl ResponseValue<ByteStream> {
218 #[doc(hidden)]
219 pub fn stream(response: reqwest::Response) -> Self {
220 let status = response.status();
221 let headers = response.headers().clone();
222 Self {
223 inner: ByteStream(Box::pin(response.bytes_stream())),
224 status,
225 headers,
226 }
227 }
228}
229
230impl ResponseValue<()> {
231 #[doc(hidden)]
232 pub fn empty(response: reqwest::Response) -> Self {
233 let status = response.status();
234 let headers = response.headers().clone();
235 Self {
238 inner: (),
239 status,
240 headers,
241 }
242 }
243}
244
245impl<T> ResponseValue<T> {
246 pub fn new(inner: T, status: reqwest::StatusCode, headers: reqwest::header::HeaderMap) -> Self {
250 Self {
251 inner,
252 status,
253 headers,
254 }
255 }
256
257 pub fn into_inner(self) -> T {
259 self.inner
260 }
261
262 pub fn status(&self) -> reqwest::StatusCode {
264 self.status
265 }
266
267 pub fn headers(&self) -> &reqwest::header::HeaderMap {
269 &self.headers
270 }
271
272 pub fn content_length(&self) -> Option<u64> {
275 self.headers
276 .get(reqwest::header::CONTENT_LENGTH)?
277 .to_str()
278 .ok()?
279 .parse::<u64>()
280 .ok()
281 }
282
283 #[doc(hidden)]
284 pub fn map<U: std::fmt::Debug, F, E>(self, f: F) -> Result<ResponseValue<U>, E>
285 where
286 F: FnOnce(T) -> U,
287 {
288 let Self {
289 inner,
290 status,
291 headers,
292 } = self;
293
294 Ok(ResponseValue {
295 inner: f(inner),
296 status,
297 headers,
298 })
299 }
300}
301
302impl ResponseValue<ByteStream> {
303 pub fn into_inner_stream(self) -> InnerByteStream {
305 self.into_inner().into_inner()
306 }
307}
308
309impl<T> Deref for ResponseValue<T> {
310 type Target = T;
311
312 fn deref(&self) -> &Self::Target {
313 &self.inner
314 }
315}
316
317impl<T> DerefMut for ResponseValue<T> {
318 fn deref_mut(&mut self) -> &mut Self::Target {
319 &mut self.inner
320 }
321}
322
323impl<T> AsRef<T> for ResponseValue<T> {
324 fn as_ref(&self) -> &T {
325 &self.inner
326 }
327}
328
329impl<T: std::fmt::Debug> std::fmt::Debug for ResponseValue<T> {
330 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
331 self.inner.fmt(f)
332 }
333}
334
335pub enum Error<E = ()> {
341 InvalidRequest(String),
343
344 CommunicationError(reqwest::Error),
346
347 InvalidUpgrade(reqwest::Error),
349
350 ErrorResponse(ResponseValue<E>),
352
353 ResponseBodyError(reqwest::Error),
355
356 InvalidResponsePayload(Bytes, serde_json::Error),
358
359 UnexpectedResponse(reqwest::Response),
362
363 Custom(String),
365}
366
367impl<E> Error<E> {
368 pub fn status(&self) -> Option<reqwest::StatusCode> {
370 match self {
371 Error::InvalidRequest(_) => None,
372 Error::Custom(_) => None,
373 Error::CommunicationError(e) => e.status(),
374 Error::ErrorResponse(rv) => Some(rv.status()),
375 Error::InvalidUpgrade(e) => e.status(),
376 Error::ResponseBodyError(e) => e.status(),
377 Error::InvalidResponsePayload(_, _) => None,
378 Error::UnexpectedResponse(r) => Some(r.status()),
379 }
380 }
381
382 pub fn into_untyped(self) -> Error {
387 match self {
388 Error::InvalidRequest(s) => Error::InvalidRequest(s),
389 Error::Custom(s) => Error::Custom(s),
390 Error::CommunicationError(e) => Error::CommunicationError(e),
391 Error::ErrorResponse(ResponseValue {
392 inner: _,
393 status,
394 headers,
395 }) => Error::ErrorResponse(ResponseValue {
396 inner: (),
397 status,
398 headers,
399 }),
400 Error::InvalidUpgrade(e) => Error::InvalidUpgrade(e),
401 Error::ResponseBodyError(e) => Error::ResponseBodyError(e),
402 Error::InvalidResponsePayload(b, e) => Error::InvalidResponsePayload(b, e),
403 Error::UnexpectedResponse(r) => Error::UnexpectedResponse(r),
404 }
405 }
406}
407
408impl<E> From<std::convert::Infallible> for Error<E> {
409 fn from(x: std::convert::Infallible) -> Self {
410 match x {}
411 }
412}
413
414impl<E> From<reqwest::Error> for Error<E> {
415 fn from(e: reqwest::Error) -> Self {
416 Self::CommunicationError(e)
417 }
418}
419
420impl<E> From<reqwest::header::InvalidHeaderValue> for Error<E> {
421 fn from(e: reqwest::header::InvalidHeaderValue) -> Self {
422 Self::InvalidRequest(e.to_string())
423 }
424}
425
426impl<E> std::fmt::Display for Error<E>
427where
428 ResponseValue<E>: ErrorFormat,
429{
430 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
431 match self {
432 Error::InvalidRequest(s) => {
433 write!(f, "Invalid Request: {}", s)?;
434 }
435 Error::CommunicationError(e) => {
436 write!(f, "Communication Error: {}", e)?;
437 }
438 Error::ErrorResponse(rve) => {
439 write!(f, "Error Response: ")?;
440 rve.fmt_info(f)?;
441 }
442 Error::InvalidUpgrade(e) => {
443 write!(f, "Invalid Response Upgrade: {}", e)?;
444 }
445 Error::ResponseBodyError(e) => {
446 write!(f, "Invalid Response Body Bytes: {}", e)?;
447 }
448 Error::InvalidResponsePayload(b, e) => {
449 write!(f, "Invalid Response Payload ({:?}): {}", b, e)?;
450 }
451 Error::UnexpectedResponse(r) => {
452 write!(f, "Unexpected Response: {:?}", r)?;
453 }
454 Error::Custom(s) => {
455 write!(f, "Error: {}", s)?;
456 }
457 }
458
459 if f.alternate() {
460 use std::error::Error as _;
461
462 let mut src = self.source().and_then(|e| e.source());
463 while let Some(s) = src {
464 write!(f, ": {s}")?;
465 src = s.source();
466 }
467 }
468 Ok(())
469 }
470}
471
472trait ErrorFormat {
473 fn fmt_info(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
474}
475
476impl<E> ErrorFormat for ResponseValue<E>
477where
478 E: std::fmt::Debug,
479{
480 fn fmt_info(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
481 write!(
482 f,
483 "status: {}; headers: {:?}; value: {:?}",
484 self.status, self.headers, self.inner,
485 )
486 }
487}
488
489impl ErrorFormat for ResponseValue<ByteStream> {
490 fn fmt_info(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
491 write!(
492 f,
493 "status: {}; headers: {:?}; value: <stream>",
494 self.status, self.headers,
495 )
496 }
497}
498
499impl<E> std::fmt::Debug for Error<E>
500where
501 ResponseValue<E>: ErrorFormat,
502{
503 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
504 std::fmt::Display::fmt(self, f)
505 }
506}
507impl<E> std::error::Error for Error<E>
508where
509 ResponseValue<E>: ErrorFormat,
510{
511 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
512 match self {
513 Error::CommunicationError(e) => Some(e),
514 Error::InvalidUpgrade(e) => Some(e),
515 Error::ResponseBodyError(e) => Some(e),
516 Error::InvalidResponsePayload(_b, e) => Some(e),
517 _ => None,
518 }
519 }
520}
521
522const PATH_SET: &percent_encoding::AsciiSet = &percent_encoding::CONTROLS
524 .add(b' ')
525 .add(b'"')
526 .add(b'#')
527 .add(b'<')
528 .add(b'>')
529 .add(b'?')
530 .add(b'`')
531 .add(b'{')
532 .add(b'}')
533 .add(b'/')
534 .add(b'%');
535
536#[doc(hidden)]
537pub fn encode_path(pc: &str) -> String {
539 percent_encoding::utf8_percent_encode(pc, PATH_SET).to_string()
540}
541
542#[doc(hidden)]
543pub trait RequestBuilderExt<E> {
544 fn form_urlencoded<T: Serialize + ?Sized>(self, body: &T) -> Result<RequestBuilder, Error<E>>;
545}
546
547impl<E> RequestBuilderExt<E> for RequestBuilder {
548 fn form_urlencoded<T: Serialize + ?Sized>(self, body: &T) -> Result<Self, Error<E>> {
549 Ok(self
550 .header(
551 reqwest::header::CONTENT_TYPE,
552 reqwest::header::HeaderValue::from_static("application/x-www-form-urlencoded"),
553 )
554 .body(
555 serde_urlencoded::to_string(body)
556 .map_err(|_| Error::InvalidRequest("failed to serialize body".to_string()))?,
557 ))
558 }
559}
560
561#[doc(hidden)]
562pub struct QueryParam<'a, T> {
563 name: &'a str,
564 value: &'a T,
565}
566
567impl<'a, T> QueryParam<'a, T> {
568 #[doc(hidden)]
569 pub fn new(name: &'a str, value: &'a T) -> Self {
570 Self { name, value }
571 }
572}
573impl<T> Serialize for QueryParam<'_, T>
574where
575 T: Serialize,
576{
577 fn serialize<S>(&self, inner: S) -> Result<S::Ok, S::Error>
578 where
579 S: serde::Serializer,
580 {
581 let serializer = QuerySerializer {
582 inner,
583 name: self.name,
584 };
585 self.value.serialize(serializer)
586 }
587}
588
589pub(crate) struct QuerySerializer<'a, S> {
590 inner: S,
591 name: &'a str,
592}
593
594macro_rules! serialize_scalar {
595 ($f:ident, $t:ty) => {
596 fn $f(self, v: $t) -> Result<Self::Ok, Self::Error> {
597 [(self.name, v)].serialize(self.inner)
598 }
599 };
600}
601
602impl<'a, S> serde::Serializer for QuerySerializer<'a, S>
603where
604 S: serde::Serializer,
605{
606 type Ok = S::Ok;
607 type Error = S::Error;
608 type SerializeSeq = QuerySeq<'a, S::SerializeSeq>;
609 type SerializeTuple = S::SerializeTuple;
610 type SerializeTupleStruct = S::SerializeTupleStruct;
611 type SerializeTupleVariant = S::SerializeTupleVariant;
612 type SerializeMap = S::SerializeMap;
613 type SerializeStruct = S::SerializeStruct;
614 type SerializeStructVariant = S::SerializeStructVariant;
615
616 serialize_scalar!(serialize_bool, bool);
617 serialize_scalar!(serialize_i8, i8);
618 serialize_scalar!(serialize_i16, i16);
619 serialize_scalar!(serialize_i32, i32);
620 serialize_scalar!(serialize_i64, i64);
621 serialize_scalar!(serialize_u8, u8);
622 serialize_scalar!(serialize_u16, u16);
623 serialize_scalar!(serialize_u32, u32);
624 serialize_scalar!(serialize_u64, u64);
625 serialize_scalar!(serialize_f32, f32);
626 serialize_scalar!(serialize_f64, f64);
627 serialize_scalar!(serialize_char, char);
628 serialize_scalar!(serialize_str, &str);
629
630 fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
631 self.inner.serialize_bytes(v)
632 }
633
634 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
635 self.inner.serialize_none()
636 }
637
638 fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
639 where
640 T: ?Sized + Serialize,
641 {
642 value.serialize(self)
645 }
646
647 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
648 self.inner.serialize_unit()
649 }
650
651 fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
652 self.inner.serialize_unit_struct(name)
653 }
654
655 fn serialize_unit_variant(
656 self,
657 _name: &'static str,
658 _variant_index: u32,
659 variant: &'static str,
660 ) -> Result<Self::Ok, Self::Error> {
661 variant.serialize(self)
665 }
666
667 fn serialize_newtype_struct<T>(
668 self,
669 name: &'static str,
670 value: &T,
671 ) -> Result<Self::Ok, Self::Error>
672 where
673 T: ?Sized + Serialize,
674 {
675 self.inner.serialize_newtype_struct(name, value)
676 }
677
678 fn serialize_newtype_variant<T>(
679 self,
680 name: &'static str,
681 _variant_index: u32,
682 variant: &'static str,
683 value: &T,
684 ) -> Result<Self::Ok, Self::Error>
685 where
686 T: ?Sized + Serialize,
687 {
688 let mut map = self.inner.serialize_struct(name, 1)?;
694 map.serialize_field(variant, value)?;
695 map.end()
696 }
697
698 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
699 let Self { inner, name, .. } = self;
700 Ok(QuerySeq {
701 inner: inner.serialize_seq(len)?,
702 name,
703 })
704 }
705
706 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
707 self.inner.serialize_tuple(len)
708 }
709
710 fn serialize_tuple_struct(
711 self,
712 name: &'static str,
713 len: usize,
714 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
715 self.inner.serialize_tuple_struct(name, len)
716 }
717
718 fn serialize_tuple_variant(
719 self,
720 name: &'static str,
721 variant_index: u32,
722 variant: &'static str,
723 len: usize,
724 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
725 self.inner
726 .serialize_tuple_variant(name, variant_index, variant, len)
727 }
728
729 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
730 self.inner.serialize_map(len)
731 }
732
733 fn serialize_struct(
734 self,
735 name: &'static str,
736 len: usize,
737 ) -> Result<Self::SerializeStruct, Self::Error> {
738 self.inner.serialize_struct(name, len)
739 }
740
741 fn serialize_struct_variant(
742 self,
743 name: &'static str,
744 variant_index: u32,
745 variant: &'static str,
746 len: usize,
747 ) -> Result<Self::SerializeStructVariant, Self::Error> {
748 self.inner
749 .serialize_struct_variant(name, variant_index, variant, len)
750 }
751}
752
753#[doc(hidden)]
754pub struct QuerySeq<'a, S> {
755 inner: S,
756 name: &'a str,
757}
758
759impl<S> serde::ser::SerializeSeq for QuerySeq<'_, S>
760where
761 S: serde::ser::SerializeSeq,
762{
763 type Ok = S::Ok;
764
765 type Error = S::Error;
766
767 fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
768 where
769 T: ?Sized + Serialize,
770 {
771 let v = (self.name, value);
772 self.inner.serialize_element(&v)
773 }
774
775 fn end(self) -> Result<Self::Ok, Self::Error> {
776 self.inner.end()
777 }
778}