Skip to main content

titan_api_codec/transform/
gzip.rs

1//! Defines transforms that utilize [gzip] to compress and decompress data.
2//!
3//! [gzip]: https://www.gzip.org/
4
5use super::common::BinaryTransform;
6
7use std::io::prelude::*;
8
9use bytes::{Buf, Bytes};
10use flate2::bufread::{GzDecoder, GzEncoder};
11use flate2::Compression;
12
13/// Transform that applies gzip compression to the input.
14#[derive(Default)]
15pub struct GzipCompressor {
16    level: Compression,
17}
18
19impl GzipCompressor {
20    /// Creates a new Gzip compressor with the given compression level.
21    pub fn new(level: Compression) -> Self {
22        Self { level }
23    }
24}
25
26impl BinaryTransform for GzipCompressor {
27    fn transform(&self, data: Bytes) -> Result<Bytes, std::io::Error> {
28        let mut enc = GzEncoder::new(data.reader(), self.level);
29        let mut buffer = Vec::new();
30        enc.read_to_end(&mut buffer)?;
31        Ok(buffer.into())
32    }
33}
34
35/// Transform that takes gzip-compressed data and inflates it back to its original content.
36#[derive(Default)]
37pub struct GzipDecompressor {}
38
39impl BinaryTransform for GzipDecompressor {
40    fn transform(&self, data: Bytes) -> Result<Bytes, std::io::Error> {
41        let mut dec = GzDecoder::new(data.reader());
42        let mut buffer = Vec::new();
43        dec.read_to_end(&mut buffer)?;
44        Ok(buffer.into())
45    }
46}
47
48#[cfg(test)]
49mod test {
50    use super::{GzipCompressor, GzipDecompressor};
51    use crate::transform::BinaryTransform;
52    use bytes::Bytes;
53    use lipsum::lipsum;
54
55    #[test]
56    fn test_roundtrip_default() {
57        let compressor = GzipCompressor::default();
58        let decompressor = GzipDecompressor::default();
59
60        let data = Bytes::from(lipsum(1000));
61
62        let compressed = compressor
63            .transform(data.clone())
64            .expect("should compress via zstd");
65        let uncompressed = decompressor
66            .transform(compressed)
67            .expect("should decompress from zstd");
68
69        assert_eq!(data, uncompressed);
70    }
71}