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}