use super::{Headers, StatusCode};
#[derive(Debug, Clone, Default)]
pub struct Body {
bytes: Vec<u8>,
}
impl Body {
pub fn empty() -> Body {
Body { bytes: Vec::new() }
}
pub fn as_bytes(&self) -> &[u8] {
&self.bytes
}
pub fn len(&self) -> usize {
self.bytes.len()
}
pub fn is_empty(&self) -> bool {
self.bytes.is_empty()
}
pub(crate) fn into_bytes(self) -> Vec<u8> {
self.bytes
}
}
impl From<Vec<u8>> for Body {
fn from(bytes: Vec<u8>) -> Body {
Body { bytes }
}
}
impl From<&[u8]> for Body {
fn from(bytes: &[u8]) -> Body {
Body {
bytes: bytes.to_vec(),
}
}
}
impl From<String> for Body {
fn from(s: String) -> Body {
Body {
bytes: s.into_bytes(),
}
}
}
impl From<&str> for Body {
fn from(s: &str) -> Body {
Body {
bytes: s.as_bytes().to_vec(),
}
}
}
#[derive(Debug, Clone)]
pub struct Response {
status: StatusCode,
headers: Headers,
body: Body,
}
impl Response {
pub fn new(status: StatusCode) -> Response {
Response {
status,
headers: Headers::new(),
body: Body::empty(),
}
}
pub fn text(body: impl Into<String>) -> Response {
Response::new(StatusCode::OK)
.header("Content-Type", "text/plain; charset=utf-8")
.body(body.into())
}
pub fn html(body: impl Into<String>) -> Response {
Response::new(StatusCode::OK)
.header("Content-Type", "text/html; charset=utf-8")
.body(body.into())
}
pub fn status(status: StatusCode) -> Response {
let page = format!("{} {}\n", status.code(), status.reason());
if status.is_bodyless() {
Response::new(status)
} else {
Response::new(status)
.header("Content-Type", "text/plain; charset=utf-8")
.body(page)
}
}
pub fn redirect(status: StatusCode, location: impl Into<String>) -> Response {
Response::new(status).header("Location", location.into())
}
pub fn header(mut self, name: impl Into<String>, value: impl Into<String>) -> Response {
self.headers.append(name, value);
self
}
pub fn body(mut self, body: impl Into<Body>) -> Response {
self.body = body.into();
self
}
pub fn status_code(&self) -> StatusCode {
self.status
}
pub fn headers_mut(&mut self) -> &mut Headers {
&mut self.headers
}
pub fn headers(&self) -> &Headers {
&self.headers
}
pub fn body_ref(&self) -> &Body {
&self.body
}
pub(crate) fn into_parts(self) -> (StatusCode, Headers, Vec<u8>) {
(self.status, self.headers, self.body.into_bytes())
}
#[cfg_attr(not(feature = "compress"), allow(dead_code))]
pub(crate) fn from_parts(status: StatusCode, headers: Headers, body: Vec<u8>) -> Response {
Response {
status,
headers,
body: Body::from(body),
}
}
}