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 `fmt::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, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 match self {
41 Self::NotFoundStream => {
42 write!(f, "Not found stream")
43 }
44 Self::ConnectionClosed => {
45 write!(f, "Connection has been closed")
46 }
47 Self::Terminated => {
48 write!(f, "Current processing has been terminated")
49 }
50 Self::Send(error) => write!(f, "Send error{COLON_SPACE}{error}"),
51 Self::FlushError(error) => write!(f, "Flush error{COLON_SPACE}{error}"),
52 Self::Unknown => write!(f, "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(|values| values.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(|values| values.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.get(key.as_ref()).map(|values| values.len())
289 }
290
291 /// Gets the number of values for a specific header key.
292 ///
293 /// # Arguments
294 ///
295 /// - `AsRef<str>` - The header key to count (must implement AsRef<str>).
296 ///
297 /// # Returns
298 ///
299 /// - `usize` - The count of values for the header.
300 ///
301 /// # Panics
302 ///
303 /// This function will panic if the header key is not found.
304 #[inline(always)]
305 pub fn get_header_size<K>(&self, key: K) -> usize
306 where
307 K: AsRef<str>,
308 {
309 self.try_get_header_size(key).unwrap()
310 }
311
312 /// Gets the total number of header values in the response.
313 ///
314 /// This counts all values across all headers, so a header with multiple values
315 /// will contribute more than one to the total count.
316 ///
317 /// # Returns
318 ///
319 /// - `usize` - The total count of all header values.
320 #[inline(always)]
321 pub fn get_headers_values_size(&self) -> usize {
322 self.headers.values().map(|values| values.len()).sum()
323 }
324
325 /// Retrieves the body content of the response as a UTF-8 encoded string.
326 ///
327 /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as_ref a string.
328 /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
329 ///
330 /// # Returns
331 ///
332 /// - `String` - The body content as a string.
333 #[inline(always)]
334 pub fn get_body_string(&self) -> String {
335 String::from_utf8_lossy(self.get_body()).into_owned()
336 }
337
338 /// Deserializes the body content of the response as_ref a specified type `T`.
339 ///
340 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
341 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
342 ///
343 /// # Arguments
344 ///
345 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
346 ///
347 /// # Returns
348 ///
349 /// - `Result<T, serde_json::Error>` - The deserialization result.
350 pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
351 where
352 T: DeserializeOwned,
353 {
354 serde_json::from_slice(self.get_body())
355 }
356
357 /// Deserializes the body content of the response as_ref a specified type `T`.
358 ///
359 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
360 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
361 ///
362 /// # Arguments
363 ///
364 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
365 ///
366 /// # Returns
367 ///
368 /// - `T` - The deserialized body content.
369 ///
370 /// # Panics
371 ///
372 /// This function will panic if the deserialization fails.
373 pub fn get_body_json<T>(&self) -> T
374 where
375 T: DeserializeOwned,
376 {
377 self.try_get_body_json().unwrap()
378 }
379
380 /// Determines whether the header should be skipped during setting.
381 ///
382 /// - Returns `true` if the header is empty or not allowed.
383 /// - Returns `false` if the header can be set.
384 #[inline(always)]
385 fn should_skip_header(&self, key: &ResponseHeadersKey) -> bool {
386 key.trim().is_empty() || key == CONTENT_LENGTH
387 }
388
389 /// Sets a header in the response, replacing any existing values.
390 ///
391 /// This function replaces all existing values for a header with a single new value.
392 ///
393 /// # Arguments
394 ///
395 /// - `AsRef<str>` - The header key (must implement AsRef<str>).
396 /// - `AsRef<str>` - The header value (must implement AsRef<String>).
397 ///
398 /// # Returns
399 ///
400 /// - `&mut Self` - A mutable reference to self for chaining.
401 #[inline(always)]
402 fn set_header_without_check<K, V>(&mut self, key: K, value: V) -> &mut Self
403 where
404 K: AsRef<str>,
405 V: AsRef<str>,
406 {
407 let mut deque: VecDeque<String> = VecDeque::with_capacity(1);
408 deque.push_back(value.as_ref().to_owned());
409 self.headers.insert(key.as_ref().to_owned(), deque);
410 self
411 }
412
413 /// Sets a header in the response, replacing any existing values.
414 ///
415 /// This function replaces all existing values for a header with a single new value.
416 ///
417 /// # Arguments
418 ///
419 /// - `AsRef<str>` - The header key (must implement AsRef<str>).
420 /// - `AsRef<str>` - The header value (must implement AsRef<String>).
421 ///
422 /// # Returns
423 ///
424 /// - `&mut Self` - A mutable reference to self for chaining.
425 #[inline(always)]
426 pub fn set_header<K, V>(&mut self, key: K, value: V) -> &mut Self
427 where
428 K: AsRef<str>,
429 V: AsRef<str>,
430 {
431 let key: ResponseHeadersKey = key.as_ref().to_owned();
432 if self.should_skip_header(&key) {
433 return self;
434 }
435 let mut deque: VecDeque<String> = VecDeque::with_capacity(1);
436 deque.push_back(value.as_ref().to_owned());
437 self.headers.insert(key, deque);
438 self
439 }
440
441 /// Adds a header to the response.
442 ///
443 /// This function appends a value to the response headers.
444 /// If the header already exists, the new value will be added to the existing values.
445 ///
446 /// # Arguments
447 ///
448 /// - `AsRef<str>` - The header key (must implement AsRef<str>).
449 /// - `AsRef<str>` - The header value (must implement AsRef<String>).
450 ///
451 /// # Returns
452 ///
453 /// - `&mut Self` - A mutable reference to self for chaining.
454 #[inline(always)]
455 pub fn add_header<K, V>(&mut self, key: K, value: V) -> &mut Self
456 where
457 K: AsRef<str>,
458 V: AsRef<str>,
459 {
460 let key: ResponseHeadersKey = key.as_ref().to_owned();
461 if self.should_skip_header(&key) {
462 return self;
463 }
464 self.headers
465 .entry(key)
466 .or_default()
467 .push_back(value.as_ref().to_owned());
468 self
469 }
470
471 /// Removes a header from the response.
472 ///
473 /// This function removes all values for the specified header key.
474 ///
475 /// # Arguments
476 ///
477 /// - `AsRef<str>` - The header key to remove (must implement AsRef<str>).
478 ///
479 /// # Returns
480 ///
481 /// - `&mut Self` - A mutable reference to self for chaining.
482 #[inline(always)]
483 pub fn remove_header<K>(&mut self, key: K) -> &mut Self
484 where
485 K: AsRef<str>,
486 {
487 let _ = self.headers.remove(key.as_ref()).is_some();
488 self
489 }
490
491 /// Removes a specific value from a header in the response.
492 ///
493 /// This function removes only the specified value from the header.
494 /// If the header has multiple values, only the matching value is removed.
495 /// If this was the last value for the header, the entire header is removed.
496 ///
497 /// # Arguments
498 ///
499 /// - `AsRef<str>` - The header key (must implement AsRef<str>).
500 /// - `AsRef<str>` - The value to remove (must implement AsRef<String>).
501 ///
502 /// # Returns
503 ///
504 /// - `&mut Self` - A mutable reference to self for chaining.
505 #[inline(always)]
506 pub fn remove_header_value<K, V>(&mut self, key: K, value: V) -> &mut Self
507 where
508 K: AsRef<str>,
509 V: AsRef<str>,
510 {
511 let key: ResponseHeadersKey = key.as_ref().to_owned();
512 if let Some(values) = self.headers.get_mut(&key) {
513 values.retain(|v| v != &value.as_ref().to_owned());
514 if values.is_empty() {
515 self.headers.remove(&key);
516 }
517 }
518 self
519 }
520
521 /// Clears all headers from the response.
522 ///
523 /// This function removes all headers, leaving the headers map empty.
524 ///
525 /// # Returns
526 ///
527 /// - `&mut Self` - A mutable reference to self for chaining.
528 #[inline(always)]
529 pub fn clear_headers(&mut self) -> &mut Self {
530 self.headers.clear();
531 self
532 }
533
534 /// Tries to parse cookies from the `Set-Cookie` header.
535 ///
536 /// This method retrieves the last `Set-Cookie` header value and parses it
537 /// into a collection of key-value pairs representing the cookies.
538 ///
539 /// # Returns
540 ///
541 /// - `Option<Cookies>` - The parsed cookies if the `Set-Cookie` header exists, otherwise `None`.
542 #[inline(always)]
543 pub fn try_get_cookies(&self) -> Option<Cookies> {
544 self.try_get_header_back(SET_COOKIE)
545 .map(|cookie_header: String| Cookie::parse(cookie_header))
546 }
547
548 /// Parses cookies from the `Set-Cookie` headers.
549 ///
550 /// This method retrieves all `Set-Cookie` header values and parses each one
551 /// into a collection of key-value pairs representing the cookies.
552 ///
553 /// # Returns
554 ///
555 /// - `Cookies` - The parsed cookies.
556 ///
557 /// # Panics
558 ///
559 /// This function will panic if the `Set-Cookie` header is not found.
560 #[inline(always)]
561 pub fn get_cookies(&self) -> Cookies {
562 self.try_get_cookies().unwrap()
563 }
564
565 /// Tries to get a cookie value by its key from `Set-Cookie` headers.
566 ///
567 /// This method parses the cookies from all `Set-Cookie` headers,
568 /// then attempts to retrieve the value for the specified key.
569 ///
570 /// # Arguments
571 ///
572 /// - `AsRef<str>` - The cookie key (implements AsRef<str>).
573 ///
574 /// # Returns
575 ///
576 /// - `Option<CookieValue>` - The cookie value if exists.
577 #[inline(always)]
578 pub fn try_get_cookie<K>(&self, key: K) -> Option<CookieValue>
579 where
580 K: AsRef<str>,
581 {
582 self.try_get_cookies()
583 .and_then(|cookies: Cookies| cookies.get(key.as_ref()).cloned())
584 }
585
586 /// Gets a cookie value by its key from `Set-Cookie` headers.
587 ///
588 /// This method parses the cookies from all `Set-Cookie` headers,
589 /// then retrieves the value for the specified key.
590 ///
591 /// # Arguments
592 ///
593 /// - `AsRef<str>` - The cookie key (implements AsRef<str>).
594 ///
595 /// # Returns
596 ///
597 /// - `CookieValue` - The cookie value.
598 ///
599 /// # Panics
600 ///
601 /// This function will panic if the `Set-Cookie` header is not found
602 /// or the cookie key does not exist.
603 #[inline(always)]
604 pub fn get_cookie<K>(&self, key: K) -> CookieValue
605 where
606 K: AsRef<str>,
607 {
608 self.try_get_cookie(key).unwrap()
609 }
610
611 /// Builds the full HTTP response as a byte vector.
612 ///
613 /// This method constructs the complete HTTP response, including the status line,
614 /// headers, and body. It handles content encoding, content type, connection
615 /// management, and content length.
616 ///
617 /// # Returns
618 ///
619 /// - `ResponseData` - The complete HTTP response bytes.
620 pub fn build(&mut self) -> ResponseData {
621 if self.reason_phrase.is_empty() {
622 self.set_reason_phrase(HttpStatus::phrase(self.get_status_code()));
623 }
624 let mut response_string: String = String::with_capacity(DEFAULT_BUFFER_SIZE);
625 self.push_http_first_line(&mut response_string);
626 let compress_type_opt: Option<Compress> = self
627 .try_get_header_back(CONTENT_ENCODING)
628 .map(|value| value.parse::<Compress>().unwrap_or_default());
629 if self.try_get_header_back(CONNECTION).is_none() {
630 self.set_header_without_check(CONNECTION, KEEP_ALIVE);
631 }
632 let content_type: ResponseHeadersValueItem =
633 self.try_get_header_back(CONTENT_TYPE).unwrap_or_else(|| {
634 let mut content_type: String = String::with_capacity(
635 TEXT_HTML.len() + SEMICOLON_SPACE.len() + CHARSET_UTF_8.len(),
636 );
637 content_type.push_str(TEXT_HTML);
638 content_type.push_str(SEMICOLON_SPACE);
639 content_type.push_str(CHARSET_UTF_8);
640 self.set_header_without_check(CONTENT_TYPE, &content_type);
641 content_type
642 });
643 let mut body: ResponseBody = self.get_body().clone();
644 if let Some(compress_type) = compress_type_opt
645 && !compress_type.is_unknown()
646 {
647 body = compress_type
648 .encode(&body, DEFAULT_BUFFER_SIZE)
649 .into_owned();
650 }
651 if !content_type.eq_ignore_ascii_case(TEXT_EVENT_STREAM) {
652 self.set_header_without_check(CONTENT_LENGTH, body.len().to_string());
653 }
654 self.get_headers().iter().for_each(|(key, values)| {
655 for value in values.iter() {
656 Self::push_header(&mut response_string, key, value);
657 }
658 });
659 response_string.push_str(HTTP_BR);
660 let mut response_bytes: Vec<u8> = response_string.into_bytes();
661 response_bytes.extend_from_slice(&body);
662 response_bytes
663 }
664}