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