use std::{fs, time::Duration};
use super::{cookie::CookieBuilder, form::FormResponse};
#[derive(Debug, Clone, Copy)]
pub struct Status {
pub code: u16
}
impl Status {
pub fn from_u16(code: u16) -> Self {
Status {
code
}
}
pub fn from_u32(code: u32) -> Self {
Status {
code: code as u16
}
}
pub fn from_u8(code: u8) -> Self {
Status {
code: code as u16
}
}
pub fn into_u16(self) -> u16 {
self.code
}
}
impl PartialEq for Status {
fn eq(&self, other: &Self) -> bool {
self.code == other.code
}
}
impl Eq for Status {}
impl std::hash::Hash for Status {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.code.hash(state);
}
}
#[derive(Debug)]
pub struct Response {
pub status: u16,
pub headers: Vec<(String, String)>,
pub cookie: String,
pub content_type: String,
pub body: Option<String>,
pub redirect: Option<String>
}
#[allow(dead_code)]
impl Response {
pub fn new(status: Status) -> Response {
Response {
status: status.into_u16(),
headers: Vec::new(),
cookie: String::new(),
content_type: "text/plain".to_string(),
body: None,
redirect: None
}
}
pub fn redirect(&mut self, location: String) {
self.status = 302;
self.add_header("Location".to_string(), location);
}
pub fn add_header(&mut self, key: String, value: String) {
self.headers.push((key, value));
}
pub fn set_cache(&mut self, duration: Duration) {
self.add_header("Cache-Control".to_string(), format!("max-age={}", duration.as_secs()));
}
pub fn set_status(&mut self, status: u16) {
self.status = status;
}
pub fn set_cookie(&mut self, cookie: String) {
self.cookie = cookie;
}
pub fn set_cookie_from_builder(&mut self, cookie_builder: CookieBuilder) {
self.cookie = cookie_builder.build();
}
pub fn set_content_type(&mut self, content_type: String) {
self.content_type = content_type;
}
pub fn body_json(&mut self, json: serde_json::Value) {
self.set_content_type("application/json".to_string());
self.body = Some(json.to_string());
}
pub fn body_html(&mut self, html: String) {
self.set_content_type("text/html".to_string());
self.body = Some(html);
}
pub fn body_text(&mut self, text: String) {
self.set_content_type("text/plain".to_string());
self.body = Some(text);
}
pub fn body_file(&mut self, file: String) {
self.set_content_type(mime_guess::from_path(&file).first_or_octet_stream().to_string());
self.body = Some(fs::read_to_string(file).unwrap());
}
pub fn body_form(&mut self, form: FormResponse) {
self.set_content_type(form.content_type);
self.body = Some(form.body);
}
pub fn http_raw(&self) -> String {
let mut response = String::new();
response.push_str(&format!("HTTP/1.1 {}\n", self.status));
for (key, value) in &self.headers {
response.push_str(&format!("{}: {}\n", key, value));
}
response.push_str(&format!("Set-Cookie: {}\n", self.cookie));
response.push_str(&self.body.clone().unwrap_or("".to_string()));
response
}
pub fn http2_raw(&self) -> String {
let mut response = String::new();
response.push_str(&format!("HTTP/2 {}\n", self.status));
for (key, value) in &self.headers {
response.push_str(&format!("{}: {}\n", key, value));
}
response.push_str(&format!("Set-Cookie: {}\n", self.cookie));
response.push_str(&self.body.clone().unwrap_or("".to_string()));
response
}
}