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