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