Skip to main content

msg_wire/compression/
gzip.rs

1use bytes::Bytes;
2use flate2::{Compression, read::GzDecoder, write::GzEncoder};
3use std::io::{self, Read, Write};
4
5use super::{CompressionType, Compressor, Decompressor};
6
7/// A compressor that uses the gzip algorithm.
8pub struct GzipCompressor {
9    level: u32,
10}
11
12impl GzipCompressor {
13    /// Creates a new gzip compressor with the given compression level (0-9).
14    pub fn new(level: u32) -> Self {
15        Self { level }
16    }
17}
18
19impl Compressor for GzipCompressor {
20    fn compression_type(&self) -> CompressionType {
21        CompressionType::Gzip
22    }
23
24    fn compress(&self, data: &[u8]) -> Result<Bytes, io::Error> {
25        // Optimistically allocate the compressed buffer to 1/4 of the original size.
26        let mut encoder =
27            GzEncoder::new(Vec::with_capacity(data.len() / 4), Compression::new(self.level));
28
29        encoder.write_all(data)?;
30
31        let bytes = encoder.finish()?;
32
33        Ok(Bytes::from(bytes))
34    }
35}
36
37#[derive(Debug, Default)]
38pub struct GzipDecompressor;
39
40impl Decompressor for GzipDecompressor {
41    fn decompress(&self, data: &[u8]) -> Result<Bytes, io::Error> {
42        let mut decoder = GzDecoder::new(data);
43
44        let mut bytes = Vec::with_capacity(data.len() * 4);
45        decoder.read_to_end(&mut bytes)?;
46
47        Ok(Bytes::from(bytes))
48    }
49}