1use std::future::Future;
24use std::marker::PhantomData;
25use std::pin::Pin;
26use std::task::{Context, Poll};
27
28use bytes::Bytes;
29use http_body_util::{BodyExt, Collected};
30use serde::de::DeserializeOwned;
31
32mod error;
33mod future;
34
35use crate::client;
36use crate::error::Error;
37use crate::types::ErrorResponse;
38
39use self::error::BodyErrorKind;
40
41pub use self::error::BodyError;
42pub use self::future::ResponseFuture;
43
44pub(crate) type Output<T> = Result<Response<T>, Error>;
45
46#[non_exhaustive]
48pub struct NoContent;
49
50pub struct Response<T> {
52 inner: client::service::Response,
53 phantom: PhantomData<T>,
54}
55
56impl<T> Response<T> {
57 pub(crate) const fn new(inner: client::service::Response) -> Self {
58 Self {
59 inner,
60 phantom: PhantomData,
61 }
62 }
63
64 pub fn headers(&self) -> &http::HeaderMap {
66 self.inner.headers()
67 }
68
69 pub fn status(&self) -> http::StatusCode {
71 self.inner.status()
72 }
73
74 pub fn bytes(self) -> BytesFuture {
92 let body = self.inner.into_body();
93
94 let fut = async {
95 body.collect()
96 .await
97 .map(Collected::to_bytes)
98 .map_err(|err| BodyError::new(BodyErrorKind::Loading, Some(err)))
99 };
100 BytesFuture {
101 inner: Box::pin(fut),
102 }
103 }
104
105 pub fn text(self) -> TextFuture {
122 TextFuture::new(self.bytes())
123 }
124
125 fn error(self) -> ErrorResponseFuture {
126 ErrorResponseFuture::new(self.bytes())
127 }
128}
129
130impl<T: DeserializeOwned> Response<T> {
131 pub fn data(self) -> DataFuture<T> {
149 DataFuture::new(self.bytes())
150 }
151}
152
153pub struct BytesFuture {
157 inner: Pin<Box<dyn Future<Output = Result<Bytes, BodyError>> + Send + Sync>>,
158}
159
160impl Future for BytesFuture {
161 type Output = Result<Bytes, BodyError>;
162
163 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
164 self.inner.as_mut().poll(cx)
165 }
166}
167
168pub struct DataFuture<T> {
170 inner: BytesFuture,
171 phantom: PhantomData<T>,
172}
173
174impl<T> DataFuture<T> {
175 const fn new(bytes: BytesFuture) -> Self {
176 Self {
177 inner: bytes,
178 phantom: PhantomData,
179 }
180 }
181}
182
183impl<T: DeserializeOwned + Unpin> Future for DataFuture<T> {
184 type Output = Result<T, BodyError>;
185
186 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
187 match Pin::new(&mut self.inner).poll(cx) {
188 Poll::Ready(Ok(bytes)) => Poll::Ready(
189 serde_json::from_slice(&bytes).map_err(|err| BodyError::decode(bytes, err)),
190 ),
191 Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
192 Poll::Pending => Poll::Pending,
193 }
194 }
195}
196
197pub struct TextFuture {
201 inner: BytesFuture,
202}
203
204impl TextFuture {
205 const fn new(bytes: BytesFuture) -> Self {
206 Self { inner: bytes }
207 }
208}
209
210impl Future for TextFuture {
211 type Output = Result<String, BodyError>;
212
213 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
214 match Pin::new(&mut self.inner).poll(cx) {
215 Poll::Ready(Ok(bytes)) => {
216 Poll::Ready(String::from_utf8(bytes.to_vec()).map_err(|err| {
217 let utf8_error = err.utf8_error();
218 BodyError::invalid_utf8(err.into_bytes(), utf8_error)
219 }))
220 }
221 Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
222 Poll::Pending => Poll::Pending,
223 }
224 }
225}
226
227struct ErrorResponseFuture {
228 inner: DataFuture<ErrorResponse>,
229}
230
231impl ErrorResponseFuture {
232 const fn new(bytes: BytesFuture) -> Self {
233 Self {
234 inner: DataFuture::new(bytes),
235 }
236 }
237}
238
239impl Future for ErrorResponseFuture {
240 type Output = Result<ErrorResponse, BodyError>;
241
242 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
243 Pin::new(&mut self.inner).poll(cx)
244 }
245}