1use crate::body::message_body::MessageBody;
4use crate::body::BoxBody;
5use crate::request::HttpRequest;
6use crate::traits::responder::Responder;
7use http::StatusCode;
8use serde::Serialize;
9use std::fmt::Debug;
10use std::io::Write;
11use tokio::io;
12
13#[derive(Clone, Debug)]
14pub struct HttpResponse<Body = BoxBody> {
16 pub(crate) body: Body,
17 pub(crate) status_code: StatusCode,
18 pub(crate) headers: http::HeaderMap,
19 pub(crate) version: http::Version,
20}
21
22impl HttpResponse<BoxBody> {
23 pub fn new<T: TryInto<StatusCode>>(status_code: T) -> Self
25 where
26 T::Error: Debug,
27 {
28 Self {
29 body: BoxBody::new(()),
30 status_code: status_code.try_into().unwrap(),
31 headers: http::HeaderMap::new(),
32 version: http::Version::HTTP_11,
33 }
34 }
35
36 pub fn status_code(&self) -> StatusCode {
38 self.status_code
39 }
40
41 pub fn headers(&self) -> &http::HeaderMap {
43 &self.headers
44 }
45
46 pub fn headers_mut(&mut self) -> &mut http::HeaderMap {
48 &mut self.headers
49 }
50
51 pub fn set_body(self, body: BoxBody) -> Self {
53 Self { body, ..self }
54 }
55
56 pub(crate) fn to_bytes(&self) -> io::Result<Vec<u8>> {
58 let mut response_bytes = Vec::new();
59
60 let status_line = format!(
61 "{:?} {} {}\r\n",
62 self.version,
63 self.status_code.as_str(),
64 self.status_code.canonical_reason().unwrap_or("Unknown")
65 );
66
67 response_bytes.write_all(status_line.as_bytes())?;
68
69 for (key, value) in &self.headers {
70 let header_line = format!("{}: {}\r\n", key, value.to_str().unwrap());
71 response_bytes.write_all(header_line.as_bytes())?;
72 }
73
74 response_bytes.write_all(b"\r\n")?;
75
76 let body = self.clone().body.try_into_bytes().unwrap_or_default(); response_bytes.write_all(&body)?;
79
80 Ok(response_bytes)
81 }
82
83 pub fn body<B>(mut self, body: B) -> Self
108 where
109 B: MessageBody + Clone + 'static,
110 {
111 self.body = BoxBody::new(body);
112
113 self
114 }
115
116 #[allow(non_snake_case)]
117 pub fn Ok() -> Self {
119 Self::new(200)
120 }
121
122 pub fn json<B>(mut self, data: &B) -> Self
124 where
125 B: Serialize,
126 {
127 let json = serde_json::to_string(data).expect("Unable to Serialize");
128 self.headers_mut()
129 .insert("Content-Type", "application/json".parse().unwrap());
130 self.body(json)
131 }
132}
133
134impl Responder for HttpResponse<BoxBody> {
135 type Body = BoxBody;
136
137 fn respond_to(self, _req: &HttpRequest) -> HttpResponse<Self::Body> {
138 self
139 }
140}
141
142impl Responder for String {
143 type Body = BoxBody;
144
145 fn respond_to(self, _req: &HttpRequest) -> HttpResponse<Self::Body> {
146 HttpResponse::new(200).set_body(BoxBody::new(self))
147 }
148}
149
150impl Responder for &'static str {
151 type Body = BoxBody;
152
153 fn respond_to(self, _req: &HttpRequest) -> HttpResponse<Self::Body> {
154 HttpResponse::new(200).set_body(BoxBody::new(self))
155 }
156}