use std::fmt;
use crate::{Extensions, HeaderMap, HeaderName, HeaderValue, Result, StatusCode, Version};
pub struct Response<T> {
head: Head,
body: T,
}
#[derive(Default)]
pub struct Head {
pub status: StatusCode,
pub version: Version,
pub headers: HeaderMap<HeaderValue>,
pub extensions: Extensions,
_priv: (),
}
#[derive(Debug)]
pub struct Builder {
inner: Result<Head>,
}
impl Response<()> {
#[inline]
pub fn builder() -> Builder {
Builder::new()
}
}
impl<T> Response<T> {
#[inline]
pub fn new(body: T) -> Response<T> {
Response {
head: Head::new(),
body,
}
}
#[inline]
pub fn from_head(head: Head, body: T) -> Response<T> {
Response { head, body }
}
#[inline]
pub fn status(&self) -> StatusCode {
self.head.status
}
#[inline]
pub fn status_mut(&mut self) -> &mut StatusCode {
&mut self.head.status
}
#[inline]
pub fn version(&self) -> Version {
self.head.version
}
#[inline]
pub fn version_mut(&mut self) -> &mut Version {
&mut self.head.version
}
#[inline]
pub fn headers(&self) -> &HeaderMap<HeaderValue> {
&self.head.headers
}
#[inline]
pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
&mut self.head.headers
}
#[inline]
pub fn extensions(&self) -> &Extensions {
&self.head.extensions
}
#[inline]
pub fn extensions_mut(&mut self) -> &mut Extensions {
&mut self.head.extensions
}
#[inline]
pub fn body(&self) -> &T {
&self.body
}
#[inline]
pub fn body_mut(&mut self) -> &mut T {
&mut self.body
}
#[inline]
pub fn into_body(self) -> T {
self.body
}
#[inline]
pub fn into_head(self) -> (Head, T) {
(self.head, self.body)
}
#[inline]
pub fn map<F, U>(self, f: F) -> Response<U>
where
F: FnOnce(T) -> U,
{
Response {
body: f(self.body),
head: self.head,
}
}
}
impl<T: Default> Default for Response<T> {
#[inline]
fn default() -> Response<T> {
Response::new(T::default())
}
}
impl<T: fmt::Debug> fmt::Debug for Response<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Response")
.field("status", &self.status())
.field("version", &self.version())
.field("headers", self.headers())
.field("body", self.body())
.finish()
}
}
impl Head {
fn new() -> Head {
Head::default()
}
}
impl fmt::Debug for Head {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Head")
.field("status", &self.status)
.field("version", &self.version)
.field("headers", &self.headers)
.finish()
}
}
impl Builder {
#[inline]
pub fn new() -> Builder {
Builder::default()
}
pub fn status<T>(self, status: T) -> Builder
where
StatusCode: TryFrom<T>,
<StatusCode as TryFrom<T>>::Error: Into<crate::Error>,
{
self.and_then(move |mut head| {
head.status = TryFrom::try_from(status).map_err(Into::into)?;
Ok(head)
})
}
pub fn status_ref(&self) -> Option<&StatusCode> {
self.inner.as_ref().ok().map(|h| &h.status)
}
pub fn version(self, version: Version) -> Builder {
self.and_then(move |mut head| {
head.version = version;
Ok(head)
})
}
pub fn version_ref(&self) -> Option<&Version> {
self.inner.as_ref().ok().map(|h| &h.version)
}
pub fn header<K, V>(self, key: K, value: V) -> Builder
where
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<crate::Error>,
HeaderValue: TryFrom<V>,
<HeaderValue as TryFrom<V>>::Error: Into<crate::Error>,
{
self.and_then(move |mut head| {
let name = <HeaderName as TryFrom<K>>::try_from(key).map_err(Into::into)?;
let value = <HeaderValue as TryFrom<V>>::try_from(value).map_err(Into::into)?;
head.headers.append(name, value);
Ok(head)
})
}
pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> {
self.inner.as_ref().ok().map(|h| &h.headers)
}
pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> {
self.inner.as_mut().ok().map(|h| &mut h.headers)
}
pub fn extension<T>(self, extension: T) -> Builder
where
T: 'static,
{
self.and_then(move |mut 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<T>(self, body: T) -> Result<Response<T>> {
self.inner.map(move |head| Response { head, body })
}
fn and_then<F>(self, func: F) -> Self
where
F: FnOnce(Head) -> Result<Head>,
{
Builder {
inner: self.inner.and_then(func),
}
}
}
impl Default for Builder {
#[inline]
fn default() -> Builder {
Builder {
inner: Ok(Head::new()),
}
}
}