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