use std::fmt::Debug;
use std::pin::Pin;
#[cfg(all(doc, feature = "async-stream"))]
use nyquest_interface::r#async::futures_io;
use nyquest_interface::r#async::AnyAsyncResponse;
#[cfg(feature = "async-stream")]
use super::AsyncReadStream;
use crate::StatusCode;
pub struct Response {
inner: Pin<Box<dyn AnyAsyncResponse>>,
}
impl Response {
pub fn status(&self) -> StatusCode {
self.inner.status().into()
}
#[inline]
pub fn with_successful_status(self) -> crate::Result<Self> {
let status = self.status();
if status.is_successful() {
Ok(self)
} else {
Err(crate::Error::NonSuccessfulStatusCode(status))
}
}
pub fn content_length(&self) -> Option<u64> {
self.inner.content_length()
}
pub fn get_header(&self, header: &str) -> crate::Result<Vec<String>> {
Ok(self.inner.get_header(header)?)
}
pub async fn text(mut self) -> crate::Result<String> {
Ok(self.inner.as_mut().text().await?)
}
pub async fn bytes(mut self) -> crate::Result<Vec<u8>> {
Ok(self.inner.as_mut().bytes().await?)
}
#[cfg(feature = "json")]
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
pub async fn json<T: serde::de::DeserializeOwned>(self) -> crate::Result<T> {
Ok(serde_json::from_slice(&self.bytes().await?)?)
}
#[cfg(feature = "async-stream")]
#[cfg_attr(docsrs, doc(cfg(feature = "async-stream")))]
pub fn into_async_read(self) -> AsyncReadStream {
AsyncReadStream::new(self.inner)
}
}
impl From<Pin<Box<dyn AnyAsyncResponse>>> for Response {
fn from(inner: Pin<Box<dyn AnyAsyncResponse>>) -> Self {
Self { inner }
}
}
struct ResponseDebug<'a> {
inner: &'a dyn AnyAsyncResponse,
}
impl Debug for ResponseDebug<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.describe(f)
}
}
impl Debug for Response {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AsyncResponse")
.field("status", &self.status())
.field("content_length", &self.content_length())
.field(
"inner",
&ResponseDebug {
inner: &*self.inner,
},
)
.finish()
}
}