use crate::{imp, Error, HeaderName, HeaderValue};
use serde::de::DeserializeOwned;
use std::convert::TryInto;
pub struct Response(pub(crate) imp::Resp);
impl Response {
pub fn status_code(&self) -> u16 {
self.0.status()
}
pub fn status(&self) -> &str {
self.0.status_str()
}
pub async fn json<D: DeserializeOwned>(&mut self) -> Result<D, Error> {
Ok(self.0.json().await?)
}
pub async fn content(&mut self) -> Result<Vec<u8>, Error> {
Ok(self.0.bytes().await?)
}
pub async fn text(&mut self) -> Result<String, Error> {
Ok(self.0.string().await?)
}
pub fn header(
&self,
name: impl TryInto<HeaderName, Error = imp::Error>,
) -> Option<&HeaderValue> {
match name.try_into() {
Err(_) => None,
Ok(name) => self.0.get_header(name.into()).map(|v| v.into()),
}
}
pub fn all_header(
&self,
name: impl TryInto<HeaderName, Error = imp::Error>,
) -> Result<impl Iterator<Item = &HeaderValue>, Error> {
let name: HeaderName = name.try_into()?;
Ok(self.0.get_headers(name.into()).map(|v| v.into()))
}
pub fn headers(&self) -> impl Iterator<Item = (&HeaderName, &HeaderValue)> {
self.0.header_iter().map(|(n, v)| (n.into(), v.into()))
}
}
impl std::fmt::Debug for Response {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let h: Vec<(&HeaderName, &HeaderValue)> = self.headers().collect();
write!(f, "HTTP {} Header: {:?}", self.status_code(), h)
}
}
pub trait Responses {
fn status(&self) -> u16;
fn status_str(&self) -> &'static str;
async fn json<D: DeserializeOwned>(&mut self) -> Result<D, imp::Error>;
async fn bytes(&mut self) -> Result<Vec<u8>, imp::Error>;
async fn string(&mut self) -> Result<String, imp::Error>;
fn get_header(&self, name: imp::HeaderName) -> Option<&imp::HeaderValue>;
fn get_headers(&self, name: imp::HeaderName) -> impl Iterator<Item = &imp::HeaderValue>;
fn header_iter(&self) -> impl Iterator<Item = (&imp::HeaderName, &imp::HeaderValue)>;
}