http_type/response/impl.rs
1use crate::*;
2
3/// Provides a default value for `Response`.
4///
5/// Returns a new `Response` instance with all fields initialized to their default values.
6impl Default for Response {
7 fn default() -> Self {
8 Self {
9 version: HttpVersion::default(),
10 status_code: ResponseStatusCode::default(),
11 reason_phrase: ResponseReasonPhrase::default(),
12 headers: hash_map_xx_hash3_64(),
13 body: Vec::new(),
14 }
15 }
16}
17
18impl Response {
19 /// Creates a new instance of `Response`.
20 ///
21 /// # Returns
22 ///
23 /// - `Response` - A new response instance with default values.
24 #[inline]
25 pub fn new() -> Self {
26 Self::default()
27 }
28
29 /// Retrieves the value of a response header by its key.
30 ///
31 /// # Arguments
32 ///
33 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
34 ///
35 /// # Returns
36 ///
37 /// - `OptionResponseHeadersValue` - The optional header values.
38 #[inline]
39 pub fn try_get_header<K>(&self, key: K) -> OptionResponseHeadersValue
40 where
41 K: AsRef<str>,
42 {
43 self.headers.get(key.as_ref()).cloned()
44 }
45
46 /// Retrieves the first value of a response header by its key.
47 ///
48 /// # Arguments
49 ///
50 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
51 ///
52 /// # Returns
53 ///
54 /// - `OptionResponseHeadersValueItem` - The first header value if exists.
55 #[inline]
56 pub fn try_get_header_front<K>(&self, key: K) -> OptionResponseHeadersValueItem
57 where
58 K: AsRef<str>,
59 {
60 self.headers
61 .get(key.as_ref())
62 .and_then(|values| values.front().cloned())
63 }
64
65 /// Retrieves the last value of a response header by its key.
66 ///
67 /// # Arguments
68 ///
69 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
70 ///
71 /// # Returns
72 ///
73 /// - `OptionResponseHeadersValueItem` - The last header value if exists.
74 #[inline]
75 pub fn try_get_header_back<K>(&self, key: K) -> OptionResponseHeadersValueItem
76 where
77 K: AsRef<str>,
78 {
79 self.headers
80 .get(key.as_ref())
81 .and_then(|values| values.back().cloned())
82 }
83
84 /// Checks if a header exists in the response.
85 ///
86 /// # Arguments
87 ///
88 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
89 ///
90 /// # Returns
91 ///
92 /// - `bool` - Whether the header exists.
93 #[inline]
94 pub fn has_header<K>(&self, key: K) -> bool
95 where
96 K: AsRef<str>,
97 {
98 let key: ResponseHeadersKey = key.as_ref().to_lowercase();
99 self.headers.contains_key(&key)
100 }
101
102 /// Checks if a header contains a specific value.
103 ///
104 /// # Arguments
105 ///
106 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
107 /// - `AsRef<str>` - The value to search for (must implement AsRef<str>).
108 ///
109 /// # Returns
110 ///
111 /// - `bool` - Whether the header contains the value.
112 #[inline]
113 pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
114 where
115 K: AsRef<str>,
116 V: AsRef<str>,
117 {
118 if let Some(values) = self.headers.get(key.as_ref()) {
119 values.contains(&value.as_ref().to_owned())
120 } else {
121 false
122 }
123 }
124
125 /// Gets the number of headers in the response.
126 ///
127 /// # Returns
128 ///
129 /// - `usize` - The count of unique header keys.
130 #[inline]
131 pub fn get_headers_length(&self) -> usize {
132 self.headers.len()
133 }
134
135 /// Gets the number of values for a specific header key.
136 ///
137 /// # Arguments
138 ///
139 /// - `AsRef<str>` - The header key to count (must implement AsRef<str>).
140 ///
141 /// # Returns
142 ///
143 /// - `usize` - The count of values for the header.
144 #[inline]
145 pub fn get_header_length<K>(&self, key: K) -> usize
146 where
147 K: AsRef<str>,
148 {
149 self.headers
150 .get(&key.as_ref().to_lowercase())
151 .map_or(0, |values| values.len())
152 }
153
154 /// Gets the total number of header values in the response.
155 ///
156 /// This counts all values across all headers, so a header with multiple values
157 /// will contribute more than one to the total count.
158 ///
159 /// # Returns
160 ///
161 /// - `usize` - The total count of all header values.
162 #[inline]
163 pub fn get_headers_values_length(&self) -> usize {
164 self.headers.values().map(|values| values.len()).sum()
165 }
166
167 /// Retrieves the body content of the response as a UTF-8 encoded string.
168 ///
169 /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as_ref a string.
170 /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
171 ///
172 /// # Returns
173 ///
174 /// - `String` - The body content as a string.
175 #[inline]
176 pub fn get_body_string(&self) -> String {
177 String::from_utf8_lossy(self.get_body()).into_owned()
178 }
179
180 /// Deserializes the body content of the response as_ref a specified type `T`.
181 ///
182 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
183 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
184 ///
185 /// # Arguments
186 ///
187 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
188 ///
189 /// # Returns
190 ///
191 /// - `ResultJsonError<T>` - The deserialization result.
192 pub fn get_body_json<T>(&self) -> ResultJsonError<T>
193 where
194 T: DeserializeOwned,
195 {
196 json_from_slice(self.get_body())
197 }
198
199 /// Determines whether the header should be skipped during setting.
200 ///
201 /// - Returns `true` if the header is empty or not allowed.
202 /// - Returns `false` if the header can be set.
203 #[inline]
204 fn should_skip_header(&self, key: &ResponseHeadersKey) -> bool {
205 key.trim().is_empty() || key == CONTENT_LENGTH
206 }
207
208 /// Sets a header in the response, replacing any existing values.
209 ///
210 /// This function replaces all existing values for a header with a single new value.
211 ///
212 /// # Arguments
213 ///
214 /// - `AsRef<str>` - The header key (must implement AsRef<str>).
215 /// - `AsRef<str>` - The header value (must implement AsRef<String>).
216 ///
217 /// # Returns
218 ///
219 /// - `&mut Self` - A mutable reference to self for chaining.
220 #[inline]
221 fn set_header_without_check<K, V>(&mut self, key: K, value: V) -> &mut Self
222 where
223 K: AsRef<str>,
224 V: AsRef<str>,
225 {
226 let key: ResponseHeadersKey = key.as_ref().to_lowercase();
227 let mut deque: VecDeque<String> = VecDeque::with_capacity(1);
228 deque.push_back(value.as_ref().to_owned());
229 self.headers.insert(key, deque);
230 self
231 }
232
233 /// Sets a header in the response, replacing any existing values.
234 ///
235 /// This function replaces all existing values for a header with a single new value.
236 ///
237 /// # Arguments
238 ///
239 /// - `AsRef<str>` - The header key (must implement AsRef<str>).
240 /// - `AsRef<str>` - The header value (must implement AsRef<String>).
241 ///
242 /// # Returns
243 ///
244 /// - `&mut Self` - A mutable reference to self for chaining.
245 #[inline]
246 pub fn set_header<K, V>(&mut self, key: K, value: V) -> &mut Self
247 where
248 K: AsRef<str>,
249 V: AsRef<str>,
250 {
251 let key: ResponseHeadersKey = key.as_ref().to_lowercase();
252 if self.should_skip_header(&key) {
253 return self;
254 }
255 let mut deque: VecDeque<String> = VecDeque::with_capacity(1);
256 deque.push_back(value.as_ref().to_owned());
257 self.headers.insert(key, deque);
258 self
259 }
260
261 /// Adds a header to the response.
262 ///
263 /// This function appends a value to the response headers.
264 /// If the header already exists, the new value will be added to the existing values.
265 ///
266 /// # Arguments
267 ///
268 /// - `AsRef<str>` - The header key (must implement AsRef<str>).
269 /// - `AsRef<str>` - The header value (must implement AsRef<String>).
270 ///
271 /// # Returns
272 ///
273 /// - `&mut Self` - A mutable reference to self for chaining.
274 #[inline]
275 pub fn add_header<K, V>(&mut self, key: K, value: V) -> &mut Self
276 where
277 K: AsRef<str>,
278 V: AsRef<str>,
279 {
280 let key: ResponseHeadersKey = key.as_ref().to_lowercase();
281 if self.should_skip_header(&key) {
282 return self;
283 }
284 self.headers
285 .entry(key)
286 .or_default()
287 .push_back(value.as_ref().to_owned());
288 self
289 }
290
291 /// Removes a header from the response.
292 ///
293 /// This function removes all values for the specified header key.
294 ///
295 /// # Arguments
296 ///
297 /// - `AsRef<str>` - The header key to remove (must implement AsRef<str>).
298 ///
299 /// # Returns
300 ///
301 /// - `&mut Self` - A mutable reference to self for chaining.
302 #[inline]
303 pub fn remove_header<K>(&mut self, key: K) -> &mut Self
304 where
305 K: AsRef<str>,
306 {
307 let _ = self.headers.remove(&key.as_ref().to_lowercase()).is_some();
308 self
309 }
310
311 /// Removes a specific value from a header in the response.
312 ///
313 /// This function removes only the specified value from the header.
314 /// If the header has multiple values, only the matching value is removed.
315 /// If this was the last value for the header, the entire header is removed.
316 ///
317 /// # Arguments
318 ///
319 /// - `AsRef<str>` - The header key (must implement AsRef<str>).
320 /// - `AsRef<str>` - The value to remove (must implement AsRef<String>).
321 ///
322 /// # Returns
323 ///
324 /// - `&mut Self` - A mutable reference to self for chaining.
325 #[inline]
326 pub fn remove_header_value<K, V>(&mut self, key: K, value: V) -> &mut Self
327 where
328 K: AsRef<str>,
329 V: AsRef<str>,
330 {
331 let key: ResponseHeadersKey = key.as_ref().to_lowercase();
332 if let Some(values) = self.headers.get_mut(&key) {
333 values.retain(|v| v != &value.as_ref().to_owned());
334 if values.is_empty() {
335 self.headers.remove(&key);
336 }
337 }
338 self
339 }
340
341 /// Clears all headers from the response.
342 ///
343 /// This function removes all headers, leaving the headers map empty.
344 ///
345 /// # Returns
346 ///
347 /// - `&mut Self` - A mutable reference to self for chaining.
348 #[inline]
349 pub fn clear_headers(&mut self) -> &mut Self {
350 self.headers.clear();
351 self
352 }
353
354 /// Sets the body of the response.
355 ///
356 /// This method allows you to set the body of the response by converting the provided
357 /// value as_ref a `ResponseBody` type. The `body` is updated with the converted value.
358 ///
359 /// # Arguments
360 ///
361 /// - `AsRef<[u8]>` - The body content (must implement AsRef<[u8]>).
362 ///
363 /// # Returns
364 ///
365 /// - `&mut Self` - A mutable reference to self for chaining.
366 #[inline]
367 pub fn set_body<T>(&mut self, body: T) -> &mut Self
368 where
369 T: AsRef<[u8]>,
370 {
371 self.body = body.as_ref().to_owned();
372 self
373 }
374
375 /// Sets the reason phrase of the response.
376 ///
377 /// This method allows you to set the reason phrase of the response by converting the
378 /// provided value as_ref a `ResponseReasonPhrase` type. The `reason_phrase` is updated
379 /// with the converted value.
380 ///
381 /// # Arguments
382 ///
383 /// - `AsRef<str>` - The reason phrase (must implement AsRef<str>).
384 ///
385 /// # Returns
386 ///
387 /// - `&mut Self` - A mutable reference to self for chaining.
388 #[inline]
389 pub fn set_reason_phrase<T>(&mut self, reason_phrase: T) -> &mut Self
390 where
391 T: AsRef<str>,
392 {
393 self.reason_phrase = reason_phrase.as_ref().to_owned();
394 self
395 }
396
397 /// Pushes a header with a key and value as_ref the response string.
398 ///
399 /// # Arguments
400 ///
401 /// - `&mut String`: A mutable reference to the string where the header will be added.
402 /// - `&str`: The header key as a string slice (`&str`).
403 /// - `&str`: The header value as a string slice (`&str`).
404 #[inline]
405 fn push_header(response_string: &mut String, key: &str, value: &str) {
406 response_string.push_str(key);
407 response_string.push_str(COLON);
408 response_string.push_str(value);
409 response_string.push_str(HTTP_BR);
410 }
411
412 /// Pushes the first line of an HTTP response (version, status code, and reason phrase) as_ref the response string.
413 /// This corresponds to the status line of the HTTP response.
414 ///
415 /// # Arguments
416 ///
417 /// - `response_string`: A mutable reference to the string where the first line will be added.
418 #[inline]
419 fn push_http_first_line(&self, response_string: &mut String) {
420 response_string.push_str(&self.get_version().to_string());
421 response_string.push_str(SPACE);
422 response_string.push_str(&self.get_status_code().to_string());
423 response_string.push_str(SPACE);
424 response_string.push_str(self.get_reason_phrase());
425 response_string.push_str(HTTP_BR);
426 }
427
428 /// Builds the full HTTP response as a byte vector.
429 ///
430 /// This method constructs the complete HTTP response, including the status line,
431 /// headers, and body. It handles content encoding, content type, connection
432 /// management, and content length.
433 ///
434 /// # Returns
435 ///
436 /// - `ResponseData` - The complete HTTP response bytes.
437 pub fn build(&mut self) -> ResponseData {
438 if self.reason_phrase.is_empty() {
439 self.set_reason_phrase(HttpStatus::phrase(*self.get_status_code()));
440 }
441 let mut response_string: String = String::with_capacity(DEFAULT_BUFFER_SIZE);
442 self.push_http_first_line(&mut response_string);
443 let compress_type_opt: OptionCompress = self
444 .try_get_header_back(CONTENT_ENCODING)
445 .map(|value| value.parse::<Compress>().unwrap_or_default());
446 if self.try_get_header_back(CONNECTION).is_none() {
447 self.set_header_without_check(CONNECTION, KEEP_ALIVE);
448 }
449 let content_type: ResponseHeadersValueItem =
450 self.try_get_header_back(CONTENT_TYPE).unwrap_or_else(|| {
451 let mut content_type: String = String::with_capacity(
452 TEXT_HTML.len() + SEMICOLON_SPACE.len() + CHARSET_UTF_8.len(),
453 );
454 content_type.push_str(TEXT_HTML);
455 content_type.push_str(SEMICOLON_SPACE);
456 content_type.push_str(CHARSET_UTF_8);
457 self.set_header_without_check(CONTENT_TYPE, &content_type);
458 content_type
459 });
460 let mut body: ResponseBody = self.get_body().clone();
461 if let Some(compress_type) = compress_type_opt
462 && !compress_type.is_unknown()
463 {
464 body = compress_type
465 .encode(&body, DEFAULT_BUFFER_SIZE)
466 .into_owned();
467 }
468 if !content_type.eq_ignore_ascii_case(TEXT_EVENT_STREAM) {
469 self.set_header_without_check(CONTENT_LENGTH, body.len().to_string());
470 }
471 self.get_headers().iter().for_each(|(key, values)| {
472 for value in values.iter() {
473 Self::push_header(&mut response_string, key, value);
474 }
475 });
476 response_string.push_str(HTTP_BR);
477 let mut response_bytes: Vec<u8> = response_string.into_bytes();
478 response_bytes.extend_from_slice(&body);
479 response_bytes
480 }
481
482 /// Converts the response to a formatted string representation.
483 ///
484 /// This method provides a human-readable summary of the response, including its version,
485 /// status code, reason phrase, headers, and body information.
486 ///
487 /// # Returns
488 ///
489 /// A `String` containing formatted response details.
490 #[inline]
491 pub fn get_string(&self) -> String {
492 let body: &Vec<u8> = self.get_body();
493 let body_type: &'static str = if std::str::from_utf8(body).is_ok() {
494 PLAIN
495 } else {
496 BINARY
497 };
498 format!(
499 "[Response] => [version]: {}; [status code]: {}; [reason]: {}; [headers]: {:?}; [body]: {} bytes {};",
500 self.get_version(),
501 self.get_status_code(),
502 self.get_reason_phrase(),
503 self.get_headers(),
504 body.len(),
505 body_type
506 )
507 }
508}