use std::{any::Any, convert::Infallible};
use thiserror::Error;
use crate::{header::HeaderMap, status::StatusCodeError, Body, Extensions, StatusCode, Version};
#[derive(Debug, Default)]
pub struct Response {
pub status: StatusCode,
pub version: Version,
pub headers: HeaderMap,
pub extensions: Extensions,
pub body: Body,
}
#[derive(Debug, Default)]
pub struct ResponseParts {
pub status: StatusCode,
pub version: Version,
pub headers: HeaderMap,
pub extensions: Extensions,
}
impl ResponseParts {
pub fn as_ref(&mut self) -> ResponsePartsRef<'_> {
ResponsePartsRef {
status: &mut self.status,
version: &mut self.version,
headers: &mut self.headers,
extensions: &mut self.extensions,
}
}
}
impl Response {
pub fn parts_mut(&mut self) -> ResponsePartsRef<'_> {
ResponsePartsRef {
status: &mut self.status,
version: &mut self.version,
headers: &mut self.headers,
extensions: &mut self.extensions,
}
}
}
#[derive(Debug)]
pub struct ResponsePartsRef<'a> {
pub status: &'a mut StatusCode,
pub version: &'a mut Version,
pub headers: &'a mut HeaderMap,
pub extensions: &'a mut Extensions,
}
impl ResponseParts {
pub fn new() -> ResponseParts {
Default::default()
}
}
#[derive(Error, Debug)]
pub enum ResponseBuilderError {
#[error("")]
Infallible(#[from] Infallible),
#[error("status code error: {0}")]
StatusCode(#[from] StatusCodeError),
}
#[derive(Debug)]
pub struct Builder {
inner: Result<Response, ResponseBuilderError>,
}
impl Response {
pub fn builder() -> Builder {
Builder::new()
}
pub fn new(body: impl Into<Body>) -> Response {
Self::from_parts(Default::default(), body)
}
pub fn from_parts(parts: ResponseParts, body: impl Into<Body>) -> Response {
Response {
status: parts.status,
version: parts.version,
headers: parts.headers,
extensions: parts.extensions,
body: body.into(),
}
}
pub fn into_parts(self) -> (ResponseParts, Body) {
(
ResponseParts {
status: self.status,
version: self.version,
headers: self.headers,
extensions: self.extensions,
},
self.body,
)
}
pub fn with_status(mut self, status: StatusCode) -> Self {
self.status = status;
self
}
}
impl Builder {
pub fn new() -> Builder {
Builder::default()
}
pub fn status<T>(self, status: T) -> Builder
where
StatusCode: TryFrom<T>,
<StatusCode as TryFrom<T>>::Error: Into<StatusCodeError>,
{
self.and_then(move |mut head| {
head.status = TryFrom::try_from(status).map_err(Into::into)?;
Ok(head)
})
}
pub fn version(self, version: Version) -> Builder {
self.and_then(move |mut head| {
head.version = version;
Ok(head)
})
}
pub fn header(self, name: impl AsRef<str>, value: impl Into<String>) -> Builder {
self.and_then(move |mut head| {
head.headers.insert(name, value);
Ok(head)
})
}
pub fn headers_ref(&self) -> Option<&HeaderMap> {
self.inner.as_ref().ok().map(|h| &h.headers)
}
pub fn headers_mut(&mut self) -> Option<&mut HeaderMap> {
self.inner.as_mut().ok().map(|h| &mut h.headers)
}
pub fn extension<T>(self, extension: T) -> Builder
where
T: Any + Send + Sync + 'static,
{
self.and_then(move |head| {
head.extensions.insert(extension);
Ok(head)
})
}
pub fn extensions_ref(&self) -> Option<&Extensions> {
self.inner.as_ref().ok().map(|h| &h.extensions)
}
pub fn extensions_mut(&mut self) -> Option<&mut Extensions> {
self.inner.as_mut().ok().map(|h| &mut h.extensions)
}
pub fn body(self, body: impl Into<Body>) -> Result<Response, ResponseBuilderError> {
self.inner.map(move |mut head| {
head.body = body.into();
head
})
}
fn and_then<F>(self, func: F) -> Self
where
F: FnOnce(Response) -> Result<Response, ResponseBuilderError>,
{
Builder {
inner: self.inner.and_then(func),
}
}
}
impl Default for Builder {
fn default() -> Builder {
Builder {
inner: Ok(Default::default()),
}
}
}