1use hyper::{Body, Response as HyperResponse, StatusCode};
2use serde::Serialize;
3use std::collections::HashMap;
4
5#[derive(Debug)]
6pub struct Response {
7 pub status: StatusCode,
8 pub headers: HashMap<String, String>,
9 pub body: Body,
10}
11
12impl Response {
13 pub fn new() -> Self {
14 Response {
15 status: StatusCode::OK,
16 headers: HashMap::new(),
17 body: Body::empty(),
18 }
19 }
20
21 pub fn status(mut self, status: StatusCode) -> Self {
22 self.status = status;
23 self
24 }
25
26 pub fn header<V: Into<String>>(mut self, key: &str, value: V) -> Self {
28 self.headers.insert(key.to_string(), value.into());
29 self
30 }
31
32 pub fn json<T: Serialize>(mut self, data: &T) -> Result<Self, serde_json::Error> {
33 let json_str = serde_json::to_string(data)?;
34 self.body = Body::from(json_str);
35 self.headers.insert("Content-Type".to_string(), "application/json".to_string());
36 Ok(self)
37 }
38
39 pub fn text(mut self, text: &str) -> Self {
40 self.body = Body::from(text.to_string());
41 self.headers.insert("Content-Type".to_string(), "text/plain".to_string());
42 self
43 }
44
45 pub fn html(mut self, html: &str) -> Self {
46 self.body = Body::from(html.to_string());
47 self.headers.insert("Content-Type".to_string(), "text/html".to_string());
48 self
49 }
50
51 pub fn body(mut self, body: Body) -> Self {
52 self.body = body;
53 self
54 }
55
56 pub fn redirect(mut self, location: &str) -> Self {
57 self.status = StatusCode::FOUND;
58 self.headers.insert("Location".to_string(), location.to_string());
59 self
60 }
61
62 pub fn into_hyper(self) -> HyperResponse<Body> {
63 let mut response = HyperResponse::builder().status(self.status);
64
65 for (key, value) in self.headers {
66 response = response.header(key, value);
67 }
68
69 response.body(self.body).unwrap()
70 }
71}
72
73impl Default for Response {
74 fn default() -> Self {
75 Self::new()
76 }
77}