Skip to main content

sark_core/http/
compress.rs

1use std::cell::RefCell;
2
3use libdeflater::{CompressionLvl, Compressor};
4
5pub struct Gzip {
6    encoder: Compressor,
7    buf: Vec<u8>,
8}
9
10impl Gzip {
11    fn new(level: i32) -> Self {
12        let lvl = CompressionLvl::new(level).unwrap_or(CompressionLvl::fastest());
13        Self {
14            encoder: Compressor::new(lvl),
15            buf: Vec::with_capacity(64 * 1024),
16        }
17    }
18
19    pub fn encode(&mut self, src: &[u8]) -> &[u8] {
20        let cap = self.encoder.gzip_compress_bound(src.len());
21        if self.buf.capacity() < cap {
22            self.buf.reserve(cap - self.buf.capacity());
23        }
24        self.buf.resize(cap, 0);
25        let n = self
26            .encoder
27            .gzip_compress(src, &mut self.buf)
28            .expect("gzip_compress_bound undersized");
29        self.buf.truncate(n);
30        &self.buf
31    }
32
33    pub fn with_thread_local<R>(f: impl FnOnce(&mut Gzip) -> R) -> R {
34        thread_local! {
35            static SLOT: RefCell<Gzip> = RefCell::new(Gzip::new(3));
36        }
37        SLOT.with(|cell| f(&mut cell.borrow_mut()))
38    }
39}