1use crate::error::Error;
4use bytes::Bytes;
5use http::StatusCode;
6use serde::Serialize;
7
8pub struct Response {
10 pub status: StatusCode,
11 pub headers: http::HeaderMap,
12 pub body: Bytes,
13}
14
15impl Response {
16 pub fn new(status: StatusCode) -> Self {
17 Self {
18 status,
19 headers: http::HeaderMap::new(),
20 body: Bytes::new(),
21 }
22 }
23
24 pub fn ok() -> Self {
25 Self::new(StatusCode::OK)
26 }
27
28 pub fn with_body(mut self, body: impl Into<Bytes>) -> Self {
29 self.body = body.into();
30 self
31 }
32
33 pub fn with_header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
34 let key = key.into();
35 let value = value.into();
36
37 if let (Ok(header_name), Ok(header_value)) = (
39 http::HeaderName::from_bytes(key.as_bytes()),
40 http::HeaderValue::from_str(&value),
41 ) {
42 self.headers.insert(header_name, header_value);
43 } else {
44 eprintln!("Warning: Invalid header {}={}", key, value);
45 }
46 self
47 }
48
49 pub fn json<T: Serialize>(data: T) -> Self {
50 match serde_json::to_vec(&data) {
51 Ok(body) => Self::ok()
52 .with_header("content-type", "application/json")
53 .with_body(body),
54 Err(e) => {
55 eprintln!("JSON serialization error: {}", e);
56 Self::new(StatusCode::INTERNAL_SERVER_ERROR)
57 .with_header("content-type", "application/json")
58 .with_body("{\"error\":\"Internal serialization error\"}")
59 }
60 }
61 }
62
63 pub fn text(text: impl Into<String>) -> Self {
64 Self::ok()
65 .with_header("content-type", "text/plain")
66 .with_body(text.into())
67 }
68
69 pub fn from_error(error: Error) -> Self {
70 let status =
71 StatusCode::from_u16(error.status_code()).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
72 let body = serde_json::json!({
73 "error": error.message(),
74 "status": error.status_code(),
75 });
76 let body_bytes =
77 serde_json::to_vec(&body).unwrap_or_else(|_| b"{\"error\":\"Unknown error\"}".to_vec());
78 Self::new(status)
79 .with_header("content-type", "application/json")
80 .with_body(body_bytes)
81 }
82
83 pub(crate) fn into_hyper(self) -> hyper::Response<http_body_util::Full<Bytes>> {
84 let mut builder = hyper::Response::builder().status(self.status);
85
86 for (key, value) in self.headers.iter() {
87 builder = builder.header(key, value);
88 }
89
90 builder
91 .body(http_body_util::Full::new(self.body))
92 .unwrap_or_else(|e| {
93 eprintln!("Failed to build response: {}", e);
94 hyper::Response::builder()
95 .status(StatusCode::INTERNAL_SERVER_ERROR)
96 .body(http_body_util::Full::new(Bytes::from(
97 "Internal Server Error",
98 )))
99 .unwrap()
100 })
101 }
102}
103
104pub struct Json<T>(pub T);
106
107impl<T: Serialize> From<Json<T>> for Response {
108 fn from(json: Json<T>) -> Self {
109 Response::json(json.0)
110 }
111}