use hyper::body::Buf;
use hyper::{header::HeaderValue, Body, HeaderMap, StatusCode};
use crate::{Error, HeaderError};
pub struct ErrorBody {
body: Body,
}
impl ErrorBody {
pub fn new(body: Body) -> Self {
Self { body }
}
pub async fn body_bytes(self) -> Result<Vec<u8>, Error> {
let buf = match hyper::body::aggregate(self.body).await {
Ok(buf) => buf,
Err(err) => return Err(Error::HttpStream(Box::new(err))),
};
Ok(buf.chunk().to_vec())
}
}
impl std::fmt::Debug for ErrorBody {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ErrorBody").finish()
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Response {
status_code: StatusCode,
headers: HeaderMap<HeaderValue>,
}
impl Response {
pub fn new(status_code: StatusCode, headers: HeaderMap<HeaderValue>) -> Self {
Self {
status_code,
headers,
}
}
pub fn status(&self) -> u16 {
self.status_code.as_u16()
}
pub fn get_header_keys(&self) -> Vec<&str> {
self.headers.keys().map(|key| key.as_str()).collect()
}
pub fn get_header_value(&self, key: &str) -> std::result::Result<Option<&str>, HeaderError> {
if let Some(value) = self.headers.get(key) {
value
.to_str()
.map(Some)
.map_err(|e| HeaderError::new(Box::new(e)))
} else {
Ok(None)
}
}
pub fn get_header_values(&self, key: &str) -> std::result::Result<Vec<&str>, HeaderError> {
self.headers
.get_all(key)
.iter()
.map(|value| value.to_str().map_err(|e| HeaderError::new(Box::new(e))))
.collect()
}
}