use crate::enums::http_body::HttpBody;
use crate::enums::http_status_code::HttpStatusCode;
use crate::enums::http_version::HttpVersion;
use crate::structures::header::header_list::HttpHeaderList;
use crate::structures::http_message::HttpMessage;
pub struct HttpResponse {
pub version: HttpVersion,
pub status_code: HttpStatusCode,
pub headers: HttpHeaderList,
pub body: HttpBody,
}
impl HttpResponse {
pub fn new(status_code: HttpStatusCode, body: HttpBody) -> Self {
HttpResponse {
version: HttpVersion::Http11,
status_code,
headers: HttpHeaderList::default(),
body,
}
}
pub fn with_headers(mut self, headers: HttpHeaderList) -> Self {
self.headers = headers;
self
}
pub fn to_message(self) -> HttpMessage {
let start_line = format!(
"{} {}",
self.version.to_string(),
self.status_code.to_string()
);
HttpMessage::new(start_line, self.headers, self.body)
}
pub fn as_bytes(self) -> Box<[u8]> {
self.to_message().as_bytes(true)
}
}
impl From<HttpResponse> for HttpMessage {
fn from(response: HttpResponse) -> Self {
response.to_message()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::str::from_utf8;
#[test]
fn test_response_construction() {
let body = HttpBody::Content("test body".into());
let response = HttpResponse::new(HttpStatusCode::Ok, body);
assert!(matches!(response.status_code, HttpStatusCode::Ok));
assert!(matches!(response.version, HttpVersion::Http11));
}
#[test]
fn test_to_bytes() {
let body = HttpBody::Content("Hello".into());
let response = HttpResponse::new(HttpStatusCode::Created, body);
let bytes = response.as_bytes();
let str_response = from_utf8(&bytes).unwrap();
assert!(str_response.contains("HTTP/1.1 201 Created"));
assert!(str_response.contains("Content-Length:5"));
assert!(str_response.ends_with("Hello"));
}
}