http_compress/compress/
impl.rs

1use super::r#type::Compress;
2use crate::{brotli, deflate, gzip};
3use http_constant::*;
4use std::{borrow::Cow, collections::HashMap, fmt, str::FromStr};
5
6impl Default for Compress {
7    fn default() -> Self {
8        Self::Unknown
9    }
10}
11
12impl FromStr for Compress {
13    type Err = ();
14
15    fn from_str(data: &str) -> Result<Self, Self::Err> {
16        match data.to_lowercase().as_str() {
17            _data if _data == CONTENT_ENCODING_GZIP => Ok(Self::Gzip),
18            _data if _data == CONTENT_ENCODING_DEFLATE => Ok(Self::Deflate),
19            _data if _data == CONTENT_ENCODING_BROTLI => Ok(Self::Br),
20            _ => Ok(Self::Unknown),
21        }
22    }
23}
24
25impl fmt::Display for Compress {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        let display_str = match *self {
28            Compress::Gzip => CONTENT_ENCODING_GZIP,
29            Compress::Deflate => CONTENT_ENCODING_DEFLATE,
30            Compress::Br => CONTENT_ENCODING_BROTLI,
31            Compress::Unknown => EMPTY_STR,
32        };
33        write!(f, "{}", display_str)
34    }
35}
36
37impl Compress {
38    /// Checks if the current instance is of the `Unknown` type.
39    ///
40    /// This method compares the current instance with the `Unknown` variant of the enum.
41    /// It returns `true` if the instance is of type `Unknown`, otherwise `false`.
42    ///
43    /// # Returns
44    /// - `true` if the instance is of type `Unknown`.
45    /// - `false` otherwise.
46    #[inline]
47    pub fn is_unknown(&self) -> bool {
48        *self == Self::Unknown
49    }
50
51    /// Extracts the compression type from an HTTP header.
52    ///
53    /// This function looks for the `Content-Encoding` header in the provided `Header` and attempts
54    /// to parse it into a `Compress` enum value.
55    ///
56    /// # Arguments
57    /// - `header` - The HTTP header from which the compression type is to be extracted.
58    ///
59    /// # Returns
60    /// - The `Compress` value corresponding to the `Content-Encoding` header, or `Compress::Unknown`
61    ///   if the header does not match any known compression types.
62    #[inline]
63    pub fn from(header: &HashMap<String, String>) -> Self {
64        let content_encoding_key: String = CONTENT_ENCODING.to_lowercase();
65        let mut compress: Compress = Self::default();
66        for (key, value) in header {
67            if key.to_lowercase() == content_encoding_key {
68                compress = value.parse::<Compress>().unwrap_or_default();
69                break;
70            }
71        }
72        compress
73    }
74
75    /// Decompresses the given data based on the selected compression algorithm.
76    ///
77    /// This method takes a byte slice of compressed data and decompresses it using one of the following
78    /// compression algorithms, depending on the variant of the enum it is called on:
79    /// - `Gzip` - Decompresses using Gzip compression.
80    /// - `Deflate` - Decompresses using Deflate compression.
81    /// - `Br` - Decompresses using Brotli compression.
82    /// - `Unknown` - Returns the input data as-is (no decompression performed).
83    ///
84    /// # Parameters
85    /// - `data` - A reference to a byte slice (`&[u8]`) containing the compressed data to be decoded.
86    /// - `buffer_size` - The buffer size to use for the decompression process. A larger buffer size can
87    ///   improve performance for larger datasets.
88    ///
89    /// # Returns
90    /// - `Cow<Vec<u8>>` - The decompressed data as a `Cow<Vec<u8>>`. If the compression algorithm
91    ///   is `Unknown`, the original data is returned unchanged, as a borrowed reference. Otherwise,
92    ///   the decompressed data is returned as an owned `Vec<u8>`.
93    #[inline]
94    pub fn decode<'a>(&self, data: &'a [u8], buffer_size: usize) -> Cow<'a, Vec<u8>> {
95        match self {
96            Self::Gzip => gzip::decode::decode(data, buffer_size),
97            Self::Deflate => deflate::decode::decode(data, buffer_size),
98            Self::Br => brotli::decode::decode(data, buffer_size),
99            Self::Unknown => Cow::Owned(data.to_vec()),
100        }
101    }
102
103    /// Compresses the given data based on the selected compression algorithm.
104    ///
105    /// This method takes a byte slice of data and compresses it using one of the following
106    /// compression algorithms, depending on the variant of the enum it is called on:
107    /// - `Gzip` - Compresses using Gzip compression.
108    /// - `Deflate` - Compresses using Deflate compression.
109    /// - `Br` - Compresses using Brotli compression.
110    /// - `Unknown` - Returns the input data as-is (no compression performed).
111    ///
112    /// # Parameters
113    /// - `data` - A reference to a byte slice (`&[u8]`) containing the data to be compressed.
114    /// - `buffer_size` - The buffer size to use for the compression process. A larger buffer size can
115    ///   improve performance for larger datasets.
116    ///
117    /// # Returns
118    /// - `Cow<Vec<u8>>` - The compressed data as a `Cow<Vec<u8>>`. If the compression algorithm
119    ///   is `Unknown`, the original data is returned unchanged, as a borrowed reference. Otherwise,
120    ///   the compressed data is returned as an owned `Vec<u8>`.
121    #[inline]
122    pub fn encode<'a>(&self, data: &'a [u8], buffer_size: usize) -> Cow<'a, Vec<u8>> {
123        match self {
124            Self::Gzip => gzip::encode::encode(data, buffer_size),
125            Self::Deflate => deflate::encode::encode(data, buffer_size),
126            Self::Br => brotli::encode::encode(data),
127            Self::Unknown => Cow::Owned(data.to_vec()),
128        }
129    }
130}