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