greyhound 0.0.1

al3x's personal backend framework
Documentation
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<serde_json::Value> for Response {
	fn from(json_value: serde_json::Value) -> Self {
		Body::from_json(&json_value)
			.map(|body| body.into())
			.unwrap_or_else(|_| Response::new(StatusCode::InternalServerError))
	}
}*/

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()
	}
}