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