use crate::http::{
self,
headers::{HeaderName, HeaderValues},
Body, Error, StatusCode,
};
use std::{
convert::TryInto,
fmt::{Debug, Display},
ops::{Deref, DerefMut, Index},
};
#[derive(Debug)]
pub struct Response {
pub(crate) res: http::Response,
pub(crate) error: Option<Error>,
}
impl Response {
pub fn new<S>(status: S) -> Self
where
S: TryInto<StatusCode>,
S::Error: Debug,
{
let res = http::Response::new(status);
Self { res, error: None }
}
pub fn builder<S>(status: S) -> Builder
where
S: TryInto<StatusCode>,
S::Error: Debug,
{
Builder::new(status)
}
#[must_use]
pub fn error(&self) -> Option<&Error> {
self.error.as_ref()
}
#[must_use]
pub fn downcast_error<E>(&self) -> Option<&E>
where
E: Display + Debug + Send + Sync + 'static,
{
self.error.as_ref()?.downcast_ref()
}
pub fn take_error(&mut self) -> Option<Error> {
self.error.take()
}
pub fn set_error(&mut self, error: impl Into<Error>) {
self.error = Some(error.into());
}
pub fn from_res<T>(value: T) -> Self
where
T: Into<http_types::Response>,
{
let res: http_types::Response = value.into();
Self { res, error: None }
}
}
impl Deref for Response {
type Target = http::Response;
fn deref(&self) -> &Self::Target {
&self.res
}
}
impl DerefMut for Response {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.res
}
}
impl AsRef<http::Response> for Response {
fn as_ref(&self) -> &http::Response {
&self.res
}
}
impl AsMut<http::Response> for Response {
fn as_mut(&mut self) -> &mut http::Response {
&mut self.res
}
}
impl AsRef<http::Headers> for Response {
fn as_ref(&self) -> &http::Headers {
self.res.as_ref()
}
}
impl AsMut<http::Headers> for Response {
fn as_mut(&mut self) -> &mut http::Headers {
self.res.as_mut()
}
}
impl From<Response> for http::Response {
fn from(response: Response) -> http_types::Response {
response.res
}
}
impl From<http::Body> for Response {
fn from(body: http::Body) -> Self {
let mut res = Response::new(200);
res.set_body(body);
res
}
}
impl From<Error> for Response {
fn from(err: Error) -> Self {
Self {
res: http::Response::new(err.status()),
error: Some(err),
}
}
}
impl From<http::Response> for Response {
fn from(res: http::Response) -> Self {
Self { res, error: None }
}
}
impl From<StatusCode> for Response {
fn from(status: StatusCode) -> Self {
let res: http::Response = status.into();
res.into()
}
}
impl From<String> for Response {
fn from(s: String) -> Self {
Body::from_string(s).into()
}
}
impl<'a> From<&'a str> for Response {
fn from(s: &'a str) -> Self {
Body::from_string(String::from(s)).into()
}
}
impl IntoIterator for Response {
type Item = (HeaderName, HeaderValues);
type IntoIter = http_types::headers::IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.res.into_iter()
}
}
impl<'a> IntoIterator for &'a Response {
type Item = (&'a HeaderName, &'a HeaderValues);
type IntoIter = http_types::headers::Iter<'a>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.res.iter()
}
}
impl<'a> IntoIterator for &'a mut Response {
type Item = (&'a HeaderName, &'a mut HeaderValues);
type IntoIter = http_types::headers::IterMut<'a>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.res.iter_mut()
}
}
impl Index<HeaderName> for Response {
type Output = HeaderValues;
#[inline]
fn index(&self, name: HeaderName) -> &HeaderValues {
&self.res[name]
}
}
impl Index<&str> for Response {
type Output = HeaderValues;
#[inline]
fn index(&self, name: &str) -> &HeaderValues {
&self.res[name]
}
}
#[derive(Debug)]
pub struct Builder(Response);
impl Builder {
pub(crate) fn new<S>(status: S) -> Self
where
S: TryInto<StatusCode>,
S::Error: std::fmt::Debug,
{
Self(Response::new(status))
}
#[must_use]
pub fn build(self) -> Response {
self.0
}
}
impl Deref for Builder {
type Target = Response;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Builder {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl From<Builder> for Response {
fn from(response_builder: Builder) -> Response {
response_builder.build()
}
}