use std::collections::HashMap;
use crate::Body;
#[derive(Debug)]
pub enum ContentType {
Json,
Xml,
Html,
PlainText,
FormUrlEncoded,
MultipartFormData,
OctetStream,
}
impl ContentType {
pub fn to_string(&self) -> String {
String::from(match self {
ContentType::Json => "application/json",
ContentType::Xml => "application/xml",
ContentType::Html => "text/html",
ContentType::PlainText => "text/plain",
ContentType::FormUrlEncoded => "application/x-www-form-urlencoded",
ContentType::MultipartFormData => "multipart/form-data",
ContentType::OctetStream => "application/octet-stream",
})
}
pub fn from_str(s: &str) -> Option<Self> {
match s {
"application/json" => Some(ContentType::Json),
"application/xml" => Some(ContentType::Xml),
"text/html" => Some(ContentType::Html),
"text/plain" => Some(ContentType::PlainText),
"application/x-www-form-urlencoded" => Some(ContentType::FormUrlEncoded),
"multipart/form-data" => Some(ContentType::MultipartFormData),
"application/octet-stream" => Some(ContentType::OctetStream),
_ => None,
}
}
}
pub struct Response {
pub status: u16,
pub headers: HashMap<String, String>,
body: Option<Body>,
}
impl Response {
pub fn new() -> Self {
Self {
status: 204,
headers: HashMap::new(),
body: None,
}
}
pub fn status(self, status: u16) -> Self {
Self { status, ..self }
}
pub fn header(self, header: impl Into<String>, value: impl Into<String>) -> Self {
let mut headers = self.headers;
headers.insert(header.into(), value.into());
Self { headers, ..self }
}
pub fn headers(self, headers: HashMap<String, String>) -> Self {
Self { headers, ..self }
}
pub fn body(self, content_type: ContentType, body: Vec<u8>) -> Self {
Self {
body: Some(Body::new(content_type, body)),
..self
}
}
pub fn into_bytes(self) -> Result<Vec<u8>, &'static str> {
let mut s = String::new();
s.push_str(&format!("HTTP/1.1 {}\r\n", self.status));
for (header, value) in self.headers {
s.push_str(&format!("{}: {}\r\n", header, value));
}
return match self.body {
Some(b) => {
s.push_str(&format!("Content-Type: {}\r\n", b.content_type.to_string()));
s.push_str(&format!("Content-Length: {}\r\n\r\n", b.data.len()));
let mut b_ = s.into_bytes();
b_.extend(b.data);
println!("{:?}", b_);
Ok(b_)
}
None => Ok(s.into_bytes()),
};
}
}