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}