Skip to content

feat!: add an unified CodecToSlice<In, Out = In> API#58

Merged
CommanderStorm merged 5 commits into
fast-pack:mainfrom
CommanderStorm:unified-api
Feb 14, 2026
Merged

feat!: add an unified CodecToSlice<In, Out = In> API#58
CommanderStorm merged 5 commits into
fast-pack:mainfrom
CommanderStorm:unified-api

Conversation

@CommanderStorm

Copy link
Copy Markdown
Collaborator

This PR adds a new trait CodecToSlice<In, Out = In>:

/// Low-level compression interface using caller-provided buffers.
///
/// Codecs write into pre-allocated slices and return a sub-slice showing exactly
/// what was written. Works across FFI boundaries and allows buffer reuse.
///
/// # Type Parameters
///
/// - `In`: Input data type (e.g., `u32` or `u64` for integer codecs)
/// - `Out`: Compressed output type (defaults to `In`, but may differ - e.g.,
///   64-bit integers compress to 32-bit words: `CodecToSlice<u64, u32>`)
///
/// # Buffer Sizing
///
/// Caller must ensure output buffers are large enough. For compression, estimate
/// `input.len() * 2 + 1024`. For decompression, size depends on the codec.
pub trait CodecToSlice<In, Out = In> {
    /// Error type returned by compression/decompression operations.
    type Error;

    /// Compresses input into output buffer, returning slice of data written.
    fn compress_to_slice<'out>(
        &mut self,
        input: &[In],
        output: &'out mut [Out],
    ) -> Result<&'out [Out], Self::Error>;

    /// Decompresses input into output buffer, returning slice of data written.
    ///
    /// Output size cannot be known in advance for some codecs (e.g., RLE).
    fn decompress_to_slice<'out>(
        &mut self,
        input: &[Out],
        output: &'out mut [In],
    ) -> Result<&'out [In], Self::Error>;
}

Here are the alternatives I have considered:

  • using bytes or Cursor based API does not work for cpp
  • using &mut Vec does not work for being zero abstraction and likely not work for cpp (because of what users would expect)
  • pub trait Codec<In, Out=In> {
      type Error;
      fn compress(&mut self, input: &[In]) -> Result<Vec<Out>, Self::Error>;
      fn decompress(&mut self, input: &[In]) -> Result<Vec<Out>, Self::Error>;
    }
    Pro: Works well for the rust world
    Con: may alocate
  • pub trait Codec {
      type CompressBuilder;
      fn compress_builder<'out>(&mut self, input: &[u32]) -> CompressBuilder<'out>;
    }
    
    pub struct CompressOp<'a> { /* ... */ }
    
    impl CompressOp<'_> {
      fn to_slice(self, output: &mut [u32]) -> Result<&[u32], Error> { ... }
      fn to_vec(self) -> Result<Vec<u32>, Error> { ... }
      fn to_buf(self, buf: impl BufMut) -> Result<usize, Error> { ... }
    }
    best of both worlds, some usage difficulty though.
    Not sure if this would be better

I chose CodecToSlice since this way we can migrate step by step and still have the "good name" Codec for the final trait that we can settle on, once we have a better idea what kind of API we really need.

@codecov

codecov Bot commented Feb 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.97744% with 12 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/rust/integer_compression/codec.rs 90.80% 6 Missing and 2 partials ⚠️
src/cpp/mod.rs 91.30% 0 Missing and 4 partials ⚠️

📢 Thoughts on this report? Let us know!

This comment was marked as resolved.

@CommanderStorm
CommanderStorm merged commit 2d5d4e7 into fast-pack:main Feb 14, 2026
10 of 11 checks passed
CommanderStorm added a commit that referenced this pull request Feb 14, 2026
This is stacked on top of #58

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants