sark_core/http/
compress.rs1use libdeflater::{CompressionLvl, Compressor};
8use o3::buffer::{InitializedSharedPool, Pooled};
9
10const GZIP_SLOTS: usize = 32;
11const GZIP_CAPACITY: usize = 256 * 1024;
12
13pub struct Gzip {
14 encoder: Compressor,
15 pool: InitializedSharedPool,
16}
17
18impl Gzip {
19 const LEVEL: i32 = 3;
20
21 pub fn new() -> Self {
22 Self::with_pool(GZIP_SLOTS, GZIP_CAPACITY)
23 }
24
25 pub fn with_pool(slots: usize, capacity: usize) -> Self {
26 let level = CompressionLvl::new(Self::LEVEL).expect("valid libdeflate compression level");
27 Self {
28 encoder: Compressor::new(level),
29 pool: InitializedSharedPool::new(slots, capacity),
30 }
31 }
32
33 pub fn encode(&mut self, src: &[u8]) -> Option<Pooled> {
34 let cap = self.encoder.gzip_compress_bound(src.len());
35 if cap > self.pool.capacity() {
36 return None;
37 }
38 let mut lease = self.pool.try_acquire()?;
39 let n = self
40 .encoder
41 .gzip_compress(src, lease.spare_mut())
42 .expect("gzip_compress_bound undersized");
43 lease
44 .try_advance(n)
45 .expect("gzip_compress_bound undersized");
46 Some(lease.freeze())
47 }
48}
49
50impl Default for Gzip {
51 fn default() -> Self {
52 Self::new()
53 }
54}