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
23#[doc(hidden)]
24pub type Frozen = pool::Span<
25    owners::Plain<pool::Fixed<{ Gzip::SLOTS.get() }, { Gzip::CAPACITY.get() }>>,
26    pool::Owned,
27    pool::Frozen,
28>;
29
30pub enum Output {
31    Plain,
32    Compressed(Frozen),
33}
34
35pub struct Gzip {
36    encoder: encoder::Encoder,
37    pool: pool::Pool<
38        state::Initialized,
39        owners::Plain<pool::Fixed<{ Gzip::SLOTS.get() }, { Gzip::CAPACITY.get() }>>,
40    >,
41}
42
43impl Gzip {
44    pub const SLOTS: num::NonZero<usize> = num::NonZero::<usize>::MIN.saturating_add(31);
45    pub const CAPACITY: num::NonZero<usize> =
46        num::NonZero::<usize>::MIN.saturating_add(256 * 1024 - 1);
47}
48
49impl Compression for Gzip {
50    fn try_new() -> Result<Self, alloc::Error> {
51        let encoder = encoder::Encoder::try_new()?;
52        let pool = pool::Pool::try_from(pool::Fixed::new())?;
53        Ok(Self { encoder, pool })
54    }
55
56    fn encode(&mut self, src: &[u8]) -> Output {
57        if src.len() <= encoder::FRAMING {
58            return Output::Plain;
59        }
60        let cap = self.encoder.bound(src.len());
61        if cap > Self::CAPACITY.get() {
62            return Output::Plain;
63        }
64        let Some(mut lease) = self.pool.acquire() else {
65            return Output::Plain;
66        };
67        let Some(()) = self.encoder.encode(src, lease.output()) else {
68            return Output::Plain;
69        };
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}