Skip to main content

http_compress/compress/
impl.rs

1use super::*;
2
3/// Enables parsing a string into a `Compress` enum variant.
4///
5/// This implementation allows converting string representations of compression
6/// algorithms (like "gzip", "deflate", "br") into their corresponding `Compress`
7/// enum variants. If the string does not match any known compression types,
8/// it defaults to `Compress::Unknown`.
9impl FromStr for Compress {
10    type Err = ();
11
12    /// Parses a string into a `Compress` enum variant.
13    ///
14    /// This method converts string representations of compression algorithms
15    /// (case-insensitive) into their corresponding `Compress` enum variants.
16    /// Unknown strings are converted to `Compress::Unknown`.
17    ///
18    /// # Arguments
19    ///
20    /// - `&str` - The string to parse, which should be a compression algorithm name.
21    ///
22    /// # Returns
23    ///
24    /// - `Result<Self, Self::Err>` - Returns `Ok` with the matching `Compress` variant,
25    ///   or `Ok(Compress::Unknown)` for unknown strings. Never returns `Err`.
26    #[inline(always)]
27    fn from_str(data: &str) -> Result<Self, Self::Err> {
28        match data.to_lowercase().as_str() {
29            _data if _data == CONTENT_ENCODING_GZIP => Ok(Self::Gzip),
30            _data if _data == CONTENT_ENCODING_DEFLATE => Ok(Self::Deflate),
31            _data if _data == CONTENT_ENCODING_BROTLI => Ok(Self::Br),
32            _ => Ok(Self::Unknown),
33        }
34    }
35}
36
37/// Implements the `Display` trait for the `Compress` enum.
38///
39/// This allows the `Compress` enum variants to be formatted as strings,
40/// typically used for outputting the `Content-Encoding` header value.
41impl fmt::Display for Compress {
42    /// Formats the `Compress` value as its `Content-Encoding` header token.
43    ///
44    /// `Compress::Unknown` formats as the empty string, since it has no
45    /// `Content-Encoding` representation.
46    ///
47    /// # Arguments
48    ///
49    /// - `&mut fmt::Formatter<'_>` - The formatter to write the value into.
50    ///
51    /// # Returns
52    ///
53    /// - `fmt::Result` - The result of the formatting operation.
54    #[inline(always)]
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        let display_str: &str = match *self {
57            Compress::Gzip => CONTENT_ENCODING_GZIP,
58            Compress::Deflate => CONTENT_ENCODING_DEFLATE,
59            Compress::Br => CONTENT_ENCODING_BROTLI,
60            Compress::Unknown => EMPTY_STR,
61        };
62        write!(f, "{display_str}")
63    }
64}
65
66/// Provides methods for interacting with the `Compress` enum.
67impl Compress {
68    /// Checks if the current instance is of the `Unknown` type.
69    ///
70    /// This method compares the current instance with the `Unknown` variant of the enum.
71    /// It returns `true` if the instance is of type `Unknown`, otherwise `false`.
72    ///
73    /// # Returns
74    ///
75    /// - `bool`: `true` if the instance is of type `Unknown`, `false` otherwise.
76    #[inline(always)]
77    pub fn is_unknown(&self) -> bool {
78        *self == Self::Unknown
79    }
80
81    /// Extracts the compression type from an HTTP header.
82    ///
83    /// This function looks for the `Content-Encoding` header in the provided `Header` and attempts
84    /// to parse it into a `Compress` enum value.
85    ///
86    /// # Arguments
87    ///
88    /// - `&HashMap<String, String, BuildHasherDefault<XxHash3_64>>` - The HTTP header from which
89    ///   the compression type is to be extracted.
90    ///
91    /// # Returns
92    ///
93    /// - `Self` - The `Compress` value corresponding to the `Content-Encoding` header, or
94    ///   `Compress::Unknown` if the header does not match any known compression types.
95    #[inline(always)]
96    pub fn from(header: &HashMap<String, String, BuildHasherDefault<XxHash3_64>>) -> Self {
97        header
98            .get(CONTENT_ENCODING)
99            .map(|value: &String| value.parse::<Compress>().unwrap_or_default())
100            .unwrap_or_default()
101    }
102
103    /// Decompresses the given data based on the selected compression algorithm.
104    ///
105    /// This method takes a byte slice of compressed data and decompresses it using one of the following
106    /// compression algorithms, depending on the variant of the enum it is called on:
107    /// - `Gzip` - Decompresses using Gzip compression.
108    /// - `Deflate` - Decompresses using Deflate compression.
109    /// - `Br` - Decompresses using Brotli compression.
110    /// - `Unknown` - Returns the input data as-is (no decompression performed).
111    ///
112    /// # Arguments
113    ///
114    /// - `&'a [u8]` - A reference to a byte slice containing the compressed data to be decoded.
115    /// - `usize` - The buffer size to use for the decompression process. A larger buffer size can
116    ///   improve performance for larger datasets.
117    ///
118    /// # Returns
119    ///
120    /// - `Cow<'a, [u8]>` - The decompressed data. If the compression algorithm
121    ///   is `Unknown`, the original data is returned unchanged, as an owned buffer. Otherwise,
122    ///   the decompressed data is returned as an owned `Vec<u8>`.
123    pub fn decode<'a>(&self, data: &'a [u8], buffer_size: usize) -> Cow<'a, [u8]> {
124        match self {
125            Self::Gzip => gzip::decode(data, buffer_size),
126            Self::Deflate => deflate::decode(data, buffer_size),
127            Self::Br => brotli::decode(data, buffer_size),
128            Self::Unknown => Cow::Owned(data.to_vec()),
129        }
130    }
131
132    /// Compresses the given data based on the selected compression algorithm.
133    ///
134    /// This method takes a byte slice of data and compresses it using one of the following
135    /// compression algorithms, depending on the variant of the enum it is called on:
136    /// - `Gzip` - Compresses using Gzip compression.
137    /// - `Deflate` - Compresses using Deflate compression.
138    /// - `Br` - Compresses using Brotli compression.
139    /// - `Unknown` - Returns the input data as-is (no compression performed).
140    ///
141    /// # Arguments
142    ///
143    /// - `&'a [u8]` - A reference to a byte slice containing the data to be compressed.
144    /// - `usize` - The buffer size to use for the compression process. A larger buffer size can
145    ///   improve performance for larger datasets.
146    ///
147    /// # Returns
148    ///
149    /// - `Cow<'a, [u8]>` - The compressed data. If the compression algorithm
150    ///   is `Unknown`, the original data is returned unchanged, as an owned buffer. Otherwise,
151    ///   the compressed data is returned as an owned `Vec<u8>`.
152    pub fn encode<'a>(&self, data: &'a [u8], buffer_size: usize) -> Cow<'a, [u8]> {
153        match self {
154            Self::Gzip => gzip::encode(data, buffer_size),
155            Self::Deflate => deflate::encode(data, buffer_size),
156            Self::Br => brotli::encode(data, buffer_size),
157            Self::Unknown => Cow::Owned(data.to_vec()),
158        }
159    }
160}