Skip to content

added support for custom configs on streaming structs#2

Open
Rick-29 wants to merge 5 commits into
cool-japan:masterfrom
Rick-29:master
Open

added support for custom configs on streaming structs#2
Rick-29 wants to merge 5 commits into
cool-japan:masterfrom
Rick-29:master

Conversation

@Rick-29
Copy link
Copy Markdown

@Rick-29 Rick-29 commented Apr 28, 2026

No description provided.

Copilot AI review requested due to automatic review settings April 28, 2026 13:53
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR adds support for custom encoding configurations to the streaming encoder/decoder types, while also gating a couple compression-related tests behind feature flags to avoid invalid builds when compression features are off.

Changes:

  • Make StreamingEncoder/StreamingDecoder generic over an encoding Config (with a default config type).
  • Add constructors for supplying a custom encoding config (and for encoder: optionally a custom StreamingConfig).
  • Gate CompressionStats tests behind compression-lz4 / compression-zstd feature flags.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
tests/compression_advanced3_test.rs Gates CompressionStats tests behind compression feature flags.
src/streaming/encoder.rs Makes StreamingEncoder generic over encoding config and adds constructors for custom configs.
src/streaming/decoder.rs Makes StreamingDecoder generic over decoding config and adds a constructor for custom config.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/streaming/encoder.rs
Comment on lines 46 to 52
pub fn with_config(writer: W, config: StreamingConfig) -> Self {
Self {
writer,
encoding_config: config::standard(),
config,
buffer: alloc::vec::Vec::new(),
items_in_buffer: 0,
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not compile: the config parameter (a StreamingConfig) shadows the imported crate::config module, so config::standard() resolves to a local variable and cannot be used as a path. Rename the parameter (e.g., streaming_config) or call the module via an unshadowed path (e.g., crate::config::standard()).

Copilot uses AI. Check for mistakes.
Comment thread src/streaming/encoder.rs
Comment on lines 104 to 109
pub fn write_item<T: Encode>(&mut self, item: &T) -> Result<()> {
// Encode item to temporary buffer
let item_writer = VecWriter::new();
let mut encoder = EncoderImpl::new(item_writer, config::standard());
let mut encoder = EncoderImpl::new(item_writer, self.encoding_config);
item.encode(&mut encoder)?;
let item_bytes = encoder.into_writer().into_vec();
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This likely moves self.encoding_config out of &mut self when constructing EncoderImpl, which will either fail to compile (if C isn't Copy) or prevent reuse of the encoder config across multiple calls. Prefer passing a reference if EncoderImpl::new supports it, or require C: Clone and pass self.encoding_config.clone() (or store the config in a shared wrapper like Arc<C>).

Copilot uses AI. Check for mistakes.
Comment thread src/streaming/decoder.rs
Comment on lines 95 to 98
// Create reader from remaining chunk data
let reader = SliceReader::new(&chunk.data[chunk.offset..]);
let mut decoder = DecoderImpl::new(reader, config::standard());
let mut decoder = DecoderImpl::new(reader, self.config);
let item = T::decode(&mut decoder)?;
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the encoder, this likely moves self.config out of &mut self when creating DecoderImpl. If C isn't Copy, this will not compile and/or will fail on subsequent calls. Consider passing &self.config (if supported) or adding a Clone bound and using self.config.clone() (or storing the config behind Arc<C>).

Copilot uses AI. Check for mistakes.
Comment thread src/streaming/decoder.rs
Comment on lines +54 to +57
/// Create a new streaming decoder with custom configuration.
/// Allows to create a decoder with specific endianness, integer encoding, and byte limits.
/// Really usefull for some performance readings (for example when reading the element number n of a p bit object) or to be compatible with some specific encoders.
pub fn new_with(reader: R, config: C) -> Self {
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling/grammar in doc comments: 'Allows to create' -> 'Allows creating', 'usefull' -> 'useful'. Consider tightening the sentence for clarity as well.

Copilot uses AI. Check for mistakes.
@cool-japan
Copy link
Copy Markdown
Owner

Thanks @Rick-29 — this is a thoughtful contribution, and the new flat module goes beyond just the original ask in #1. A few items before we can merge:

Bug — cursor not restored in FlatDecoder::get:
The current chaining (read_item()?.ok_or_else(...).and_then(...)) only restores the saved cursor when read_item() returns Ok(Some(item)). On both non-happy paths — Err(_) from read_item() (the ? short-circuits before .ok_or_else) and Ok(None) for out-of-bounds (where .ok_or_else produces Err, so .and_then is a no-op) — the reader is left positioned at idx * ITEM_SIZE instead of being restored to current. Could you wrap the operation so the seek-back runs unconditionally before returning? For example:

let result = self.read_item().and_then(|opt| {
    opt.ok_or_else(|| Error::OwnedCustom {
        message: format!("Unexpected end of file at index {idx}"),
    })
});
self.seek(SeekFrom::Start(current))?;
result

Tests: the new public API (StreamingEncoder::new_with, StreamingEncoder::new_with_config, StreamingDecoder::new_with, FlatEncoder, FlatDecoder) doesn't have any unit or integration tests in the diff. Could you add a couple of roundtrips — at minimum a flat roundtrip with a fixed-size record (e.g. u64) and a seek-then-read_item test that catches the cursor-restore bug above?

Compression test cfg guards: good catch — the two #[cfg(any(feature = "compression-lz4", feature = "compression-zstd"))] additions are correct and they fix a real --no-default-features build break for tests/compression_advanced3_test.rs. Thanks for picking that up.

Minor:

  • Typos in the new doc strings: "lenght" → "length", "usefull" → "useful".
  • The PR body is empty — a short description (and a Closes #1 link) would help future readers.
  • The branch is opened from your fork's master against cool-japan/oxicode:master, while we are shipping from branch 0.2.3. We will handle the rebase on our side at merge time — just flagging so you are not surprised.

If you can address the get bug and add a couple of tests, we will aim to land this in the 0.2.3 release.

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