1use hyper::{
2 http::header::{HeaderName, HeaderValue},
3 http::StatusCode,
4 Body,
5};
6use std::collections::HashMap;
7use std::str::FromStr;
8
9pub struct Response {
10 pub(crate) ended: bool,
11 pub(crate) status: StatusCode,
12 headers: HashMap<String, String>,
13 data: String,
14}
15
16impl Response {
17 pub fn new() -> Response {
18 Response {
19 ended: false,
20 data: String::from(""),
21 headers: HashMap::new(),
22 status: StatusCode::OK,
23 }
24 }
25
26 pub fn set_header(&mut self, name: &str, value: &str) {
28 self.headers.insert(name.to_string(), value.to_string());
29 }
30
31 pub fn status(&mut self, status: StatusCode) -> &mut Self {
32 self.status = status;
33
34 self
35 }
36
37 pub fn send<S: AsRef<str>>(&mut self, data: S) {
38 self.data = data.as_ref().to_string();
39
40 self.end();
41 }
42
43 pub fn end(&mut self) {
45 self.ended = true;
46 }
47}
48
49impl Into<hyper::Response<Body>> for Response {
50 fn into(self) -> hyper::Response<Body> {
51 let mut response = hyper::Response::new(Body::from(self.data));
52 *response.status_mut() = self.status;
53
54 self.headers
55 .into_iter()
56 .for_each(|(header_name, header_value)| {
57 response.headers_mut().insert(
58 HeaderName::from_str(&header_name).unwrap(),
59 HeaderValue::from_str(&header_value).unwrap(),
60 );
61 });
62
63 response
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn test_set_header() {
73 let mut response = Response::new();
74
75 response.set_header("my-custom-header", "a-b-c");
76
77 let res: hyper::Response<Body> = response.into();
78
79 assert_eq!(
80 res.headers().get("my-custom-header"),
81 Some(&HeaderValue::from_str("a-b-c").unwrap())
82 );
83 }
84
85 #[test]
86 fn status() {
87 let mut response = Response::new();
88
89 response.status(StatusCode::BAD_REQUEST);
90
91 let res: hyper::Response<Body> = response.into();
92
93 assert_eq!(res.status(), StatusCode::BAD_REQUEST);
94 }
95
96 #[test]
97 fn test_end() {
98 let mut response = Response::new();
99
100 assert_eq!(response.ended, false);
101
102 response.end();
103
104 assert_eq!(response.ended, true);
105 }
106
107 #[tokio::test]
108 async fn test_send() {
109 let mut response = Response::new();
110
111 response.send("Hello");
112
113 assert_eq!(response.ended, true);
114
115 let mut res: hyper::Response<Body> = response.into();
116
117 let bytes = hyper::body::to_bytes(res.body_mut()).await.unwrap();
118 let body = String::from_utf8(bytes.into_iter().collect()).unwrap();
119
120 assert_eq!(body, String::from("Hello"),);
121 }
122}