leyline/core/request/
compress.rs1#[cfg(not(all(
2 feature = "compression-gzip",
3 feature = "compression-brotli",
4 feature = "compression-zstd",
5 feature = "compression-deflate"
6)))]
7use crate::core::error::Kind;
8use crate::core::error::{Error, Result};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11#[non_exhaustive]
12pub enum ContentEncoding {
13 Gzip,
14 Brotli,
15 Zstd,
16 Deflate,
17}
18
19impl ContentEncoding {
20 pub(crate) fn header_value(self) -> &'static str {
21 match self {
22 ContentEncoding::Gzip => "gzip",
23 ContentEncoding::Brotli => "br",
24 ContentEncoding::Zstd => "zstd",
25 ContentEncoding::Deflate => "deflate",
26 }
27 }
28
29 pub(crate) fn encode(self, data: &[u8]) -> Result<Vec<u8>> {
30 match self {
31 ContentEncoding::Gzip => gzip(data),
32 ContentEncoding::Brotli => brotli(data),
33 ContentEncoding::Zstd => zstd(data),
34 ContentEncoding::Deflate => deflate(data),
35 }
36 }
37}
38
39#[cfg(feature = "compression-gzip")]
40fn gzip(data: &[u8]) -> Result<Vec<u8>> {
41 use std::io::Write;
42 let mut enc = flate2::write::GzEncoder::new(
43 Vec::with_capacity(data.len() / 2),
44 flate2::Compression::default(),
45 );
46 enc.write_all(data).map_err(Error::from)?;
47 enc.finish().map_err(Error::from)
48}
49
50#[cfg(not(feature = "compression-gzip"))]
51fn gzip(_data: &[u8]) -> Result<Vec<u8>> {
52 Err(feature_off("gzip", "compression-gzip"))
53}
54
55#[cfg(feature = "compression-brotli")]
56fn brotli(data: &[u8]) -> Result<Vec<u8>> {
57 use std::io::Read;
58 let mut out = Vec::with_capacity(data.len() / 2);
59 brotli::CompressorReader::new(data, 4096, 5, 22)
60 .read_to_end(&mut out)
61 .map_err(Error::from)?;
62 Ok(out)
63}
64
65#[cfg(not(feature = "compression-brotli"))]
66fn brotli(_data: &[u8]) -> Result<Vec<u8>> {
67 Err(feature_off("brotli", "compression-brotli"))
68}
69
70#[cfg(feature = "compression-zstd")]
71fn zstd(data: &[u8]) -> Result<Vec<u8>> {
72 zstd::encode_all(data, 3).map_err(Error::from)
73}
74
75#[cfg(not(feature = "compression-zstd"))]
76fn zstd(_data: &[u8]) -> Result<Vec<u8>> {
77 Err(feature_off("zstd", "compression-zstd"))
78}
79
80#[cfg(feature = "compression-deflate")]
81fn deflate(data: &[u8]) -> Result<Vec<u8>> {
82 use std::io::Write;
83 let mut enc = flate2::write::ZlibEncoder::new(
84 Vec::with_capacity(data.len() / 2),
85 flate2::Compression::default(),
86 );
87 enc.write_all(data).map_err(Error::from)?;
88 enc.finish().map_err(Error::from)
89}
90
91#[cfg(not(feature = "compression-deflate"))]
92fn deflate(_data: &[u8]) -> Result<Vec<u8>> {
93 Err(feature_off("deflate", "compression-deflate"))
94}
95
96#[cfg(not(all(
97 feature = "compression-gzip",
98 feature = "compression-brotli",
99 feature = "compression-zstd",
100 feature = "compression-deflate"
101)))]
102fn feature_off(codec: &str, feature: &str) -> Error {
103 Error::new(Kind::Body).with_message(format!(
104 "{codec} request compression requested but the `{feature}` feature is not compiled in"
105 ))
106}
107
108#[cfg(test)]
109mod tests;