feather_runtime/http/
response.rs

1use bytes::Bytes; 
2use http::{HeaderMap, HeaderName, HeaderValue, StatusCode};
3use serde::Serialize;
4use std::{fmt::Display, str::FromStr};
5
6#[derive(Debug, Clone, Default)]
7pub struct Response {
8    /// The HTTP status code of the response.
9    /// This is a 3-digit integer that indicates the result of the request.
10    pub status: StatusCode,
11    /// The headers of the HTTP response.
12    /// Headers are key-value pairs that provide additional information about the response.
13    pub headers: HeaderMap,
14    /// The body of the HTTP response.
15    /// This is the content that is sent back to the client.
16    /// The body is represented as a `Bytes` object for efficient handling of binary data.
17    /// But The Other Method like `json()`,`body()`can be used to get the body in different formats.
18    pub body: Option<Bytes>, 
19    /// The HTTP version of the response.
20    pub version: http::Version, 
21}
22
23impl Response {
24    /// Sets the StatusCode of the response and Returns a Muteable Reference to the Response so you can things like
25    /// ```rust
26    /// res.status(200).send_text("eyo");
27    /// ```
28    /// The StatusCode is a 3-digit integer that indicates the result of the request.    
29    pub fn status(&mut self,status: u16) -> &mut Response {
30        self.status = StatusCode::from_u16(status).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
31        self
32    }
33    /// Adds a header to the response.
34    /// The header is a key-value pair that provides additional information about the response.
35    pub fn add_header(&mut self, key: &str, value: &str) -> Option<()> {
36        if let Ok(val) = HeaderValue::from_str(value) {
37            if let Ok(key) = HeaderName::from_str(key) {
38                self.headers.insert(key, val);
39            }
40            return None;
41        }
42        None
43    }
44    /// Converts the `HttpResponse` into a raw HTTP response string.
45    pub fn to_raw(&self) -> String {
46        let mut response = format!(
47            "HTTP/1.1 {} {}\r\n",
48            self.status.as_u16(),
49            self.status.canonical_reason().unwrap_or("Unknown")
50        );
51
52        for (key, value) in &self.headers {
53            response.push_str(&format!("{}: {}\r\n", key, value.to_str().unwrap()));
54        }
55
56        response.push_str("\r\n");
57
58        if let Some(ref body) = self.body {
59            response.push_str(&String::from_utf8_lossy(body));
60        }
61        response
62    }
63
64    /// Converts the `HttpResponse` into a raw HTTP response as bytes.
65    pub fn to_bytes(&self) -> Bytes {
66        let mut response = self.to_string().into_bytes();
67        if let Some(ref body) = self.body {
68            response.extend_from_slice(body);
69        }
70
71        Bytes::from(response)
72    }
73
74    pub fn send_text(&mut self, data: impl Into<String>) {
75        let body = data.into();
76        self.body = Some(Bytes::from(body));
77        self.headers
78            .insert("Content-Type", "text/plain".parse().unwrap());
79        self.headers.insert(
80            "Content-Length",
81            self.body
82                .as_ref()
83                .unwrap()
84                .len()
85                .to_string()
86                .parse()
87                .unwrap(),
88        );
89        self.headers.insert(
90            "Date", 
91            chrono::Utc::now().to_string().parse().unwrap()
92        );
93    }
94    pub fn send_bytes(&mut self, data: impl Into<Vec<u8>>) {
95        let body = data.into();
96        self.headers.insert(
97            "Date", 
98            chrono::Utc::now().to_string().parse().unwrap()
99        );
100        self.body = Some(Bytes::from(body));
101        self.headers.insert(
102            "Content-Length",
103            self.body
104                .as_ref()
105                .unwrap()
106                .len()
107                .to_string()
108                .parse()
109                .unwrap(),
110        );
111    }
112    pub fn send_html(&mut self, data: impl Into<String>) {
113        let body = data.into();
114        self.body = Some(Bytes::from(body));
115        self.headers.insert(
116            "Date", 
117            chrono::Utc::now().to_string().parse().unwrap()
118        );
119        self.headers
120            .insert("Content-Type", "text/html".parse().unwrap());
121        self.headers.insert(
122            "Content-Length",
123            self.body
124                .as_ref()
125                .unwrap()
126                .len()
127                .to_string()
128                .parse()
129                .unwrap(),
130        );
131    }
132    pub fn send_json<T: Serialize>(&mut self, data: T) {
133        match serde_json::to_string(&data) {
134            Ok(json) => {
135                self.body = Some(Bytes::from(json));
136                self.headers.insert(
137                    "Date", 
138                    chrono::Utc::now().to_string().parse().unwrap()
139                );
140                self.headers
141                    .insert("Content-Type", HeaderValue::from_static("application/json"));
142                self.headers.insert(
143                    "Content-Length",
144                    self.body
145                        .as_ref()
146                        .unwrap()
147                        .len()
148                        .to_string()
149                        .parse()
150                        .unwrap(),
151                );
152                
153            }
154            Err(_) => {
155                self.headers.insert(
156                    "Date", 
157                    chrono::Utc::now().to_string().parse().unwrap()
158                );
159                self.status = StatusCode::INTERNAL_SERVER_ERROR;
160                self.body = Some(Bytes::from("Internal Server Error"));
161                self.headers
162                    .insert("Content-Type", HeaderValue::from_static("text/plain"));
163                self.headers.insert(
164                    "Content-Length",
165                    self.body
166                        .as_ref()
167                        .unwrap()
168                        .len()
169                        .to_string()
170                        .parse()
171                        .unwrap(),
172                );
173                
174            }
175        }
176    }
177}
178
179
180impl Display for Response {
181    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182        write!(f,"{}", self.to_string())
183    }
184}