Skip to main content

sark_http/payload/compress/
mod.rs

1use o3::buffer::pool::owners;
2
3#[doc(hidden)]
4pub mod dynamic;
5mod encoder;
6pub mod inflate;
7
8use std::num;
9
10use o3::{
11    alloc,
12    buffer::pool::{self, state},
13};
14
15/// Compression storage selected when constructing a protocol connection.
16pub trait Compression: Sized {
17    fn try_new() -> Result<Self, alloc::Error>;
18
19    /// Returns a smaller gzip body or keeps the original bytes unchanged.
20    fn encode(&mut self, bytes: &[u8]) -> Output;
21}
22
23pub enum Output {
24    Plain,
25    Compressed(
26        pool::Span<
27            owners::Plain<pool::Fixed<{ Gzip::SLOTS.get() }, { Gzip::CAPACITY.get() }>>,
28            pool::Owned,
29            pool::Frozen,
30        >,
31    ),
32}
33
34pub struct Gzip {
35    encoder: encoder::Encoder,
36    pool: pool::Pool<
37        state::Initialized,
38        owners::Plain<pool::Fixed<{ Gzip::SLOTS.get() }, { Gzip::CAPACITY.get() }>>,
39    >,
40}
41
42impl Gzip {
43    pub const SLOTS: num::NonZero<usize> = num::NonZero::<usize>::MIN.saturating_add(31);
44    pub const CAPACITY: num::NonZero<usize> =
45        num::NonZero::<usize>::MIN.saturating_add(256 * 1024 - 1);
46}
47
48impl Compression for Gzip {
49    fn try_new() -> Result<Self, alloc::Error> {
50        let encoder = encoder::Encoder::try_new()?;
51        let pool = pool::Pool::try_from(pool::Fixed::new())?;
52        Ok(Self { encoder, pool })
53    }
54
55    fn encode(&mut self, src: &[u8]) -> Output {
56        if src.len() <= encoder::FRAMING {
57            return Output::Plain;
58        }
59        let cap = self.encoder.bound(src.len());
60        if cap > Self::CAPACITY.get() {
61            return Output::Plain;
62        }
63        let Some(mut lease) = self.pool.acquire() else {
64            return Output::Plain;
65        };
66        let Some(done) = self.encoder.encode(src, lease.output()) else {
67            return Output::Plain;
68        };
69        done.commit();
70        Output::Compressed(lease.freeze())
71    }
72}
73
74impl Compression for () {
75    fn try_new() -> Result<Self, alloc::Error> {
76        Ok(())
77    }
78
79    fn encode(&mut self, _: &[u8]) -> Output {
80        Output::Plain
81    }
82}