mod into_parts;
mod into_response;
use crate::StatusCode;
pub use into_response::IntoResponse;
use jiff::Zoned;
use super::header::HeaderMap;
#[derive(Debug, Clone, Default)]
pub struct Parts {
pub status: StatusCode,
pub headers: HeaderMap,
}
#[derive(Debug, Clone, Default)]
pub struct Response {
head: Parts,
body: Option<Vec<u8>>,
}
impl Response {
pub fn new(body: Vec<u8>) -> Self {
Self {
body: Some(body),
..Default::default()
}
}
pub fn status(&self) -> &StatusCode {
&self.head.status
}
pub fn status_mut(&mut self) -> &mut StatusCode {
&mut self.head.status
}
pub fn headers(&self) -> &HeaderMap {
&self.head.headers
}
pub fn headers_mut(&mut self) -> &mut HeaderMap {
&mut self.head.headers
}
pub fn body(&self) -> &Option<Vec<u8>> {
&self.body
}
pub fn serialize_to_raw_http_response(self) -> Vec<u8> {
let mut serialized = Vec::new();
serialized.extend_from_slice(
format!(
"HTTP/1.1 {} {}\r\n",
self.head.status,
self.head.status.canonical_reason()
)
.as_bytes(),
);
for (key, values) in self.head.headers.iter() {
for value in values {
serialized.extend_from_slice(format!("{}: {}\r\n", key, value).as_bytes());
}
}
if let Some(ref body) = self.body {
serialized.extend_from_slice(format!("Content-Length: {}\r\n", body.len()).as_bytes());
}
let date = Zoned::now()
.strftime("Date: %a, %d %b %Y %H:%M:%S GMT\r\n")
.to_string();
serialized.extend_from_slice(date.as_bytes());
serialized.extend_from_slice(b"\r\n");
if let Some(body) = self.body {
serialized.extend_from_slice(&body);
}
serialized
}
}