sark_core/http/
compress.rs1use 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}