http_type/response/impl.rs
1use crate::*;
2
3/// Implements the `std::error::Error` trait for `ResponseError`.
4/// This allows `ResponseError` to be treated as a standard Rust error type.
5impl std::error::Error for ResponseError {}
6
7/// Converts an I/O error to a `ResponseError`.
8///
9/// Maps I/O errors to `Send` variant with the error message.
10impl From<std::io::Error> for ResponseError {
11 /// Converts an I/O error to a `ResponseError`.
12 ///
13 /// # Arguments
14 ///
15 /// - `std::io::Error`: The I/O error to convert.
16 ///
17 /// # Returns
18 ///
19 /// - `ResponseError`: The corresponding response error as `Send`.
20 #[inline(always)]
21 fn from(error: std::io::Error) -> Self {
22 ResponseError::Send(error.to_string())
23 }
24}
25
26/// Implements the `Display` trait for `ResponseError`.
27/// This allows `ResponseError` variants to be formatted into human-readable strings.
28impl Display for ResponseError {
29 /// Formats the `ResponseError` variant into a human-readable string.
30 ///
31 /// # Arguments
32 ///
33 /// - `f`: A mutable reference to a `Formatter` used for writing the formatted string.
34 ///
35 /// # Returns
36 ///
37 /// A `fmt::Result` indicating whether the formatting was successful.
38 #[inline(always)]
39 fn fmt(&self, data: &mut Formatter<'_>) -> fmt::Result {
40 match self {
41 Self::NotFoundStream => {
42 write!(data, "Not found stream")
43 }
44 Self::ConnectionClosed => {
45 write!(data, "Connection has been closed")
46 }
47 Self::Terminated => {
48 write!(data, "Current processing has been terminated")
49 }
50 Self::Send(error) => write!(data, "Send error{COLON_SPACE}{error}"),
51 Self::FlushError(error) => write!(data, "Flush error{COLON_SPACE}{error}"),
52 Self::Unknown => write!(data, "Unknown error"),
53 }
54 }
55}
56
57/// Provides a default value for `Response`.
58///
59/// Returns a new `Response` instance with all fields initialized to their default values.
60impl Default for Response {
61 #[inline(always)]
62 fn default() -> Self {
63 let http_status: HttpStatus = HttpStatus::default();
64 Self {
65 version: HttpVersion::Http1_1,
66 status_code: http_status.code(),
67 reason_phrase: http_status.to_string(),
68 headers: hash_map_xx_hash3_64(),
69 body: Vec::new(),
70 }
71 }
72}
73
74impl Response {
75 /// Pushes a header with a key and value as_ref the response string.
76 ///
77 /// # Arguments
78 ///
79 /// - `&mut String`: A mutable reference to the string where the header will be added.
80 /// - `&str`: The header key as a string slice (`&str`).
81 /// - `&str`: The header value as a string slice (`&str`).
82 #[inline(always)]
83 fn push_header(response_string: &mut String, key: &str, value: &str) {
84 response_string.push_str(key);
85 response_string.push_str(COLON);
86 response_string.push_str(value);
87 response_string.push_str(HTTP_BR);
88 }
89
90 /// Pushes the first line of an HTTP response (version, status code, and reason phrase) as_ref the response string.
91 /// This corresponds to the status line of the HTTP response.
92 ///
93 /// # Arguments
94 ///
95 /// - `&mut String`: A mutable reference to the string where the first line will be added.
96 #[inline(always)]
97 fn push_http_first_line(&self, response_string: &mut String) {
98 response_string.push_str(&self.get_version().to_string());
99 response_string.push_str(SPACE);
100 response_string.push_str(&self.get_status_code().to_string());
101 response_string.push_str(SPACE);
102 response_string.push_str(self.get_reason_phrase());
103 response_string.push_str(HTTP_BR);
104 }
105
106 /// Tries to retrieve the value of a response header by its key.
107 ///
108 /// # Arguments
109 ///
110 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
111 ///
112 /// # Returns
113 ///
114 /// - `Option<ResponseHeadersValue>` - The optional header values.
115 #[inline(always)]
116 pub fn try_get_header<K>(&self, key: K) -> Option<ResponseHeadersValue>
117 where
118 K: AsRef<str>,
119 {
120 self.headers.get(key.as_ref()).cloned()
121 }
122
123 /// Retrieves the value of a response header by its key.
124 ///
125 /// # Arguments
126 ///
127 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
128 ///
129 /// # Returns
130 ///
131 /// - `ResponseHeadersValue` - The optional header values.
132 ///
133 /// # Panics
134 ///
135 /// This function will panic if the header key is not found.
136 #[inline(always)]
137 pub fn get_header<K>(&self, key: K) -> ResponseHeadersValue
138 where
139 K: AsRef<str>,
140 {
141 self.try_get_header(key).unwrap()
142 }
143
144 /// Tries to retrieve the first value of a response header by its key.
145 ///
146 /// # Arguments
147 ///
148 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
149 ///
150 /// # Returns
151 ///
152 /// - `Option<ResponseHeadersValueItem>` - The first header value if exists.
153 #[inline(always)]
154 pub fn try_get_header_front<K>(&self, key: K) -> Option<ResponseHeadersValueItem>
155 where
156 K: AsRef<str>,
157 {
158 self.headers
159 .get(key.as_ref())
160 .and_then(|data: &VecDeque<String>| data.front().cloned())
161 }
162
163 /// Retrieves the first value of a response header by its key.
164 ///
165 /// # Arguments
166 ///
167 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
168 ///
169 /// # Returns
170 ///
171 /// - `ResponseHeadersValueItem` - The first header value if exists.
172 ///
173 /// # Panics
174 ///
175 /// This function will panic if the header key is not found.
176 #[inline(always)]
177 pub fn get_header_front<K>(&self, key: K) -> ResponseHeadersValueItem
178 where
179 K: AsRef<str>,
180 {
181 self.try_get_header_front(key).unwrap()
182 }
183
184 /// Tries to retrieve the last value of a response header by its key.
185 ///
186 /// # Arguments
187 ///
188 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
189 ///
190 /// # Returns
191 ///
192 /// - `Option<ResponseHeadersValueItem>` - The last header value if exists.
193 #[inline(always)]
194 pub fn try_get_header_back<K>(&self, key: K) -> Option<ResponseHeadersValueItem>
195 where
196 K: AsRef<str>,
197 {
198 self.headers
199 .get(key.as_ref())
200 .and_then(|data: &VecDeque<String>| data.back().cloned())
201 }
202
203 /// Retrieves the last value of a response header by its key.
204 ///
205 /// # Arguments
206 ///
207 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
208 ///
209 /// # Returns
210 ///
211 /// - `ResponseHeadersValueItem` - The last header value if exists.
212 ///
213 /// # Panics
214 ///
215 /// This function will panic if the header key is not found.
216 #[inline(always)]
217 pub fn get_header_back<K>(&self, key: K) -> ResponseHeadersValueItem
218 where
219 K: AsRef<str>,
220 {
221 self.try_get_header_back(key).unwrap()
222 }
223
224 /// Checks if a header exists in the response.
225 ///
226 /// # Arguments
227 ///
228 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
229 ///
230 /// # Returns
231 ///
232 /// - `bool` - Whether the header exists.
233 #[inline(always)]
234 pub fn has_header<K>(&self, key: K) -> bool
235 where
236 K: AsRef<str>,
237 {
238 self.headers.contains_key(key.as_ref())
239 }
240
241 /// Checks if a header contains a specific value.
242 ///
243 /// # Arguments
244 ///
245 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
246 /// - `AsRef<str>` - The value to search for (must implement AsRef<str>).
247 ///
248 /// # Returns
249 ///
250 /// - `bool` - Whether the header contains the value.
251 #[inline(always)]
252 pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
253 where
254 K: AsRef<str>,
255 V: AsRef<str>,
256 {
257 if let Some(values) = self.headers.get(key.as_ref()) {
258 values.contains(&value.as_ref().to_owned())
259 } else {
260 false
261 }
262 }
263
264 /// Gets the number of headers in the response.
265 ///
266 /// # Returns
267 ///
268 /// - `usize` - The count of unique header keys.
269 #[inline(always)]
270 pub fn get_headers_size(&self) -> usize {
271 self.headers.len()
272 }
273
274 /// Tries to get the number of values for a specific header key.
275 ///
276 /// # Arguments
277 ///
278 /// - `AsRef<str>` - The header key to count (must implement AsRef<str>).
279 ///
280 /// # Returns
281 ///
282 /// - `Option<usize>` - The count of values for the header.
283 #[inline(always)]
284 pub fn try_get_header_size<K>(&self, key: K) -> Option<usize>
285 where
286 K: AsRef<str>,
287 {
288 self.headers
289 .get(key.as_ref())
290 .map(|data: &VecDeque<String>| data.len())
291 }
292
293 /// Gets the number of values for a specific header key.
294 ///
295 /// # Arguments
296 ///
297 /// - `AsRef<str>` - The header key to count (must implement AsRef<str>).
298 ///
299 /// # Returns
300 ///
301 /// - `usize` - The count of values for the header.
302 ///
303 /// # Panics
304 ///
305 /// This function will panic if the header key is not found.
306 #[inline(always)]
307 pub fn get_header_size<K>(&self, key: K) -> usize
308 where
309 K: AsRef<str>,
310 {
311 self.try_get_header_size(key).unwrap()
312 }
313
314 /// Gets the total number of header values in the response.
315 ///
316 /// This counts all values across all headers, so a header with multiple values
317 /// will contribute more than one to the total count.
318 ///
319 /// # Returns
320 ///
321 /// - `usize` - The total count of all header values.
322 #[inline(always)]
323 pub fn get_headers_values_size(&self) -> usize {
324 self.headers
325 .values()
326 .map(|data: &VecDeque<String>| data.len())
327 .sum()
328 }
329
330 /// Retrieves the body content of the response as a UTF-8 encoded string.
331 ///
332 /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as_ref a string.
333 /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
334 ///
335 /// # Returns
336 ///
337 /// - `String` - The body content as a string.
338 #[inline(always)]
339 pub fn get_body_string(&self) -> String {
340 String::from_utf8_lossy(self.get_body()).into_owned()
341 }
342
343 /// Deserializes the body content of the response as_ref a specified type `T`.
344 ///
345 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
346 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
347 ///
348 /// # Arguments
349 ///
350 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
351 ///
352 /// # Returns
353 ///
354 /// - `Result<T, serde_json::Error>` - The deserialization result.
355 pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
356 where
357 T: DeserializeOwned,
358 {
359 serde_json::from_slice(self.get_body())
360 }
361
362 /// Deserializes the body content of the response as_ref a specified type `T`.
363 ///
364 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
365 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
366 ///
367 /// # Arguments
368 ///
369 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
370 ///
371 /// # Returns
372 ///
373 /// - `T` - The deserialized body content.
374 ///
375 /// # Panics
376 ///
377 /// This function will panic if the deserialization fails.
378 pub fn get_body_json<T>(&self) -> T
379 where
380 T: DeserializeOwned,
381 {
382 self.try_get_body_json().unwrap()
383 }
384
385 /// Determines whether the header should be skipped during setting.
386 ///
387 /// - Returns `true` if the header is empty or not allowed.
388 /// - Returns `false` if the header can be set.
389 #[inline(always)]
390 fn should_skip_header(&self, key: &ResponseHeadersKey) -> bool {
391 key.trim().is_empty() || key == CONTENT_LENGTH
392 }
393
394 /// Sets a header in the response, replacing any existing values.
395 ///
396 /// This function replaces all existing values for a header with a single new value.
397 ///
398 /// # Arguments
399 ///
400 /// - `AsRef<str>` - The header key (must implement AsRef<str>).
401 /// - `AsRef<str>` - The header value (must implement AsRef<String>).
402 ///
403 /// # Returns
404 ///
405 /// - `&mut Self` - A mutable reference to self for chaining.
406 #[inline(always)]
407 fn set_header_without_check<K, V>(&mut self, key: K, value: V) -> &mut Self
408 where
409 K: AsRef<str>,
410 V: AsRef<str>,
411 {
412 let mut deque: VecDeque<String> = VecDeque::with_capacity(1);
413 deque.push_back(value.as_ref().to_owned());
414 self.headers.insert(key.as_ref().to_owned(), deque);
415 self
416 }
417
418 /// Sets a header in the response, replacing any existing values.
419 ///
420 /// This function replaces all existing values for a header with a single new value.
421 ///
422 /// # Arguments
423 ///
424 /// - `AsRef<str>` - The header key (must implement AsRef<str>).
425 /// - `AsRef<str>` - The header value (must implement AsRef<String>).
426 ///
427 /// # Returns
428 ///
429 /// - `&mut Self` - A mutable reference to self for chaining.
430 #[inline(always)]
431 pub fn set_header<K, V>(&mut self, key: K, value: V) -> &mut Self
432 where
433 K: AsRef<str>,
434 V: AsRef<str>,
435 {
436 let key: ResponseHeadersKey = key.as_ref().to_owned();
437 if self.should_skip_header(&key) {
438 return self;
439 }
440 let mut deque: VecDeque<String> = VecDeque::with_capacity(1);
441 deque.push_back(value.as_ref().to_owned());
442 self.headers.insert(key, deque);
443 self
444 }
445
446 /// Adds a header to the response.
447 ///
448 /// This function appends a value to the response headers.
449 /// If the header already exists, the new value will be added to the existing values.
450 ///
451 /// # Arguments
452 ///
453 /// - `AsRef<str>` - The header key (must implement AsRef<str>).
454 /// - `AsRef<str>` - The header value (must implement AsRef<String>).
455 ///
456 /// # Returns
457 ///
458 /// - `&mut Self` - A mutable reference to self for chaining.
459 #[inline(always)]
460 pub fn add_header<K, V>(&mut self, key: K, value: V) -> &mut Self
461 where
462 K: AsRef<str>,
463 V: AsRef<str>,
464 {
465 let key: ResponseHeadersKey = key.as_ref().to_owned();
466 if self.should_skip_header(&key) {
467 return self;
468 }
469 self.headers
470 .entry(key)
471 .or_default()
472 .push_back(value.as_ref().to_owned());
473 self
474 }
475
476 /// Removes a header from the response.
477 ///
478 /// This function removes all values for the specified header key.
479 ///
480 /// # Arguments
481 ///
482 /// - `AsRef<str>` - The header key to remove (must implement AsRef<str>).
483 ///
484 /// # Returns
485 ///
486 /// - `&mut Self` - A mutable reference to self for chaining.
487 #[inline(always)]
488 pub fn remove_header<K>(&mut self, key: K) -> &mut Self
489 where
490 K: AsRef<str>,
491 {
492 let _ = self.headers.remove(key.as_ref()).is_some();
493 self
494 }
495
496 /// Removes a specific value from a header in the response.
497 ///
498 /// This function removes only the specified value from the header.
499 /// If the header has multiple values, only the matching value is removed.
500 /// If this was the last value for the header, the entire header is removed.
501 ///
502 /// # Arguments
503 ///
504 /// - `AsRef<str>` - The header key (must implement AsRef<str>).
505 /// - `AsRef<str>` - The value to remove (must implement AsRef<String>).
506 ///
507 /// # Returns
508 ///
509 /// - `&mut Self` - A mutable reference to self for chaining.
510 #[inline(always)]
511 pub fn remove_header_value<K, V>(&mut self, key: K, value: V) -> &mut Self
512 where
513 K: AsRef<str>,
514 V: AsRef<str>,
515 {
516 let key: ResponseHeadersKey = key.as_ref().to_owned();
517 if let Some(values) = self.headers.get_mut(&key) {
518 values.retain(|data: &String| data != &value.as_ref().to_owned());
519 if values.is_empty() {
520 self.headers.remove(&key);
521 }
522 }
523 self
524 }
525
526 /// Clears all headers from the response.
527 ///
528 /// This function removes all headers, leaving the headers map empty.
529 ///
530 /// # Returns
531 ///
532 /// - `&mut Self` - A mutable reference to self for chaining.
533 #[inline(always)]
534 pub fn clear_headers(&mut self) -> &mut Self {
535 self.headers.clear();
536 self
537 }
538
539 /// Tries to parse cookies from the `Set-Cookie` header.
540 ///
541 /// This method retrieves the last `Set-Cookie` header value and parses it
542 /// into a collection of key-value pairs representing the cookies.
543 ///
544 /// # Returns
545 ///
546 /// - `Option<Cookies>` - The parsed cookies if the `Set-Cookie` header exists, otherwise `None`.
547 #[inline(always)]
548 pub fn try_get_cookies(&self) -> Option<Cookies> {
549 self.try_get_header_back(SET_COOKIE)
550 .map(|cookie_header: String| Cookie::parse(cookie_header))
551 }
552
553 /// Parses cookies from the `Set-Cookie` headers.
554 ///
555 /// This method retrieves all `Set-Cookie` header values and parses each one
556 /// into a collection of key-value pairs representing the cookies.
557 ///
558 /// # Returns
559 ///
560 /// - `Cookies` - The parsed cookies.
561 ///
562 /// # Panics
563 ///
564 /// This function will panic if the `Set-Cookie` header is not found.
565 #[inline(always)]
566 pub fn get_cookies(&self) -> Cookies {
567 self.try_get_cookies().unwrap()
568 }
569
570 /// Tries to get a cookie value by its key from `Set-Cookie` headers.
571 ///
572 /// This method parses the cookies from all `Set-Cookie` headers,
573 /// then attempts to retrieve the value for the specified key.
574 ///
575 /// # Arguments
576 ///
577 /// - `AsRef<str>` - The cookie key (implements AsRef<str>).
578 ///
579 /// # Returns
580 ///
581 /// - `Option<CookieValue>` - The cookie value if exists.
582 #[inline(always)]
583 pub fn try_get_cookie<K>(&self, key: K) -> Option<CookieValue>
584 where
585 K: AsRef<str>,
586 {
587 self.try_get_cookies()
588 .and_then(|cookies: Cookies| cookies.get(key.as_ref()).cloned())
589 }
590
591 /// Gets a cookie value by its key from `Set-Cookie` headers.
592 ///
593 /// This method parses the cookies from all `Set-Cookie` headers,
594 /// then retrieves the value for the specified key.
595 ///
596 /// # Arguments
597 ///
598 /// - `AsRef<str>` - The cookie key (implements AsRef<str>).
599 ///
600 /// # Returns
601 ///
602 /// - `CookieValue` - The cookie value.
603 ///
604 /// # Panics
605 ///
606 /// This function will panic if the `Set-Cookie` header is not found
607 /// or the cookie key does not exist.
608 #[inline(always)]
609 pub fn get_cookie<K>(&self, key: K) -> CookieValue
610 where
611 K: AsRef<str>,
612 {
613 self.try_get_cookie(key).unwrap()
614 }
615
616 /// Builds the full HTTP response as a byte vector.
617 ///
618 /// This method constructs the complete HTTP response, including the status line,
619 /// headers, and body. It handles content encoding, content type, connection
620 /// management, and content length.
621 ///
622 /// # Returns
623 ///
624 /// - `ResponseData` - The complete HTTP response bytes.
625 pub fn build(&mut self) -> ResponseData {
626 if self.reason_phrase.is_empty() {
627 self.set_reason_phrase(HttpStatus::phrase(self.get_status_code()));
628 }
629 let mut response_string: String = String::with_capacity(DEFAULT_BUFFER_SIZE);
630 self.push_http_first_line(&mut response_string);
631 let compress_type_opt: Option<Compress> = self
632 .try_get_header_back(CONTENT_ENCODING)
633 .map(|data: String| data.parse::<Compress>().unwrap_or_default());
634 if self.try_get_header_back(CONNECTION).is_none() {
635 self.set_header_without_check(CONNECTION, KEEP_ALIVE);
636 }
637 let content_type: ResponseHeadersValueItem =
638 self.try_get_header_back(CONTENT_TYPE).unwrap_or_else(|| {
639 let mut content_type: String = String::with_capacity(
640 TEXT_HTML.len() + SEMICOLON_SPACE.len() + CHARSET_UTF_8.len(),
641 );
642 content_type.push_str(TEXT_HTML);
643 content_type.push_str(SEMICOLON_SPACE);
644 content_type.push_str(CHARSET_UTF_8);
645 self.set_header_without_check(CONTENT_TYPE, &content_type);
646 content_type
647 });
648 let mut body: ResponseBody = self.get_body().clone();
649 if let Some(compress_type) = compress_type_opt
650 && !compress_type.is_unknown()
651 {
652 body = compress_type
653 .encode(&body, DEFAULT_BUFFER_SIZE)
654 .into_owned();
655 }
656 if !content_type.eq_ignore_ascii_case(TEXT_EVENT_STREAM) {
657 self.set_header_without_check(CONTENT_LENGTH, body.len().to_string());
658 }
659 self.get_headers()
660 .iter()
661 .for_each(|header_entry: (&String, &VecDeque<String>)| {
662 let (header_key, header_values): (&String, &VecDeque<String>) = header_entry;
663 for header_value in header_values.iter() {
664 Self::push_header(&mut response_string, header_key, header_value);
665 }
666 });
667 response_string.push_str(HTTP_BR);
668 let mut response_bytes: Vec<u8> = response_string.into_bytes();
669 response_bytes.extend_from_slice(&body);
670 response_bytes
671 }
672}