use bytes::Bytes;
use http::{HeaderMap, StatusCode};
use serde::Serialize;
pub struct Response {
status: StatusCode,
headers: HeaderMap,
body: Bytes,
}
impl Response {
pub fn new() -> Self {
Self {
status: StatusCode::OK,
headers: HeaderMap::new(),
body: Bytes::new(),
}
}
pub fn status(mut self, status: StatusCode) -> Self {
self.status = status;
self
}
pub fn header(mut self, key: &str, value: &str) -> Self {
if let (Ok(name), Ok(val)) = (
http::header::HeaderName::from_bytes(key.as_bytes()),
http::header::HeaderValue::from_str(value),
) {
self.headers.insert(name, val);
}
self
}
pub fn text(text: String) -> Self {
Self {
status: StatusCode::OK,
headers: HeaderMap::new(),
body: Bytes::from(text),
}
}
pub fn json<T: Serialize>(value: &T) -> crate::Result<Self> {
let json_string = serde_json::to_string(value)
.map_err(crate::Error::JsonSerializeError)?;
Ok(Self {
status: StatusCode::OK,
headers: HeaderMap::new(),
body: Bytes::from(json_string),
}
.header("Content-Type", "application/json"))
}
pub fn body(mut self, body: String) -> Self {
self.body = Bytes::from(body);
self
}
pub fn body_bytes(mut self, body: Bytes) -> Self {
self.body = body;
self
}
pub fn html(html: String) -> Self {
Self {
status: StatusCode::OK,
headers: HeaderMap::new(),
body: Bytes::from(html),
}
.header("Content-Type", "text/html; charset=utf-8")
}
pub fn not_found() -> Self {
Self {
status: StatusCode::NOT_FOUND,
headers: HeaderMap::new(),
body: Bytes::from("Not Found"),
}
}
pub fn bad_request(message: String) -> Self {
Self {
status: StatusCode::BAD_REQUEST,
headers: HeaderMap::new(),
body: Bytes::from(message),
}
}
pub fn internal_error(message: String) -> Self {
Self {
status: StatusCode::INTERNAL_SERVER_ERROR,
headers: HeaderMap::new(),
body: Bytes::from(message),
}
}
pub fn redirect(location: &str) -> Self {
Self {
status: StatusCode::FOUND,
headers: HeaderMap::new(),
body: Bytes::new(),
}
.header("Location", location)
}
pub fn no_content() -> Self {
Self {
status: StatusCode::NO_CONTENT,
headers: HeaderMap::new(),
body: Bytes::new(),
}
}
pub fn get_status(&self) -> StatusCode {
self.status
}
pub fn get_headers(&self) -> &HeaderMap {
&self.headers
}
pub fn get_body(&self) -> &Bytes {
&self.body
}
}
impl Default for Response {
fn default() -> Self {
Self::new()
}
}
impl From<Response> for hyper::Response<http_body_util::Full<Bytes>> {
fn from(response: Response) -> Self {
let mut builder = hyper::Response::builder()
.status(response.status);
for (key, value) in response.headers.iter() {
builder = builder.header(key, value);
}
builder
.body(http_body_util::Full::new(response.body))
.expect("Failed to build hyper response")
}
}