jam1garner / jam1garner/binrw

TakeSeek + until_eof with enum pre asserts

Open
#217 1 comment 0 reactions 0 assignees View on GitHub
confusing api
Dominant language
Rust
Stars
853
Forks
56
PR merge metrics
No merged PRs in 30d

Description

Example:
```rust
use binrw::{io::TakeSeekExt, until_eof, BinRead};

fn main() { let data = std::fs::read("/home/minus/test.bin").unwrap();
let mut cursor = std::io::Cursor::new(&data);
let data = Data::read(&mut cursor).unwrap();
println!("Data: {:?}", data);
}

#[derive(Debug, BinRead)]
#[br(little)]
struct Data {
v: u8,
garbage: u8,
#[br(map_stream = |s| s.take_seek(16), parse_with = |r, e, _:()| until_eof(r, e, (v,)))]
data: Vec,
}

#[derive(Debug, BinRead)]
#[br(little, import(v: u8))]
enum Thing {
#[br(pre_assert(v == 0x00))]
Thing0(Thing0),
#[br(pre_assert(v == 0x01))]
Thing1(Thing1),
}

#[derive(Debug, BinRead)]
#[br(little)]
struct Thing0 {
#[br(dbg)]
val0: u16,
}

#[derive(Debug, BinRead)]
#[br(little)]
pub struct Thing1 {
#[br(dbg)]
val1: u16,
}
```
And I just made a 16byte file to test it with.
(Side question: is there a better way to pass args to the inner part with until eof?)

This results in a panic.
```bash
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value:
╺━━━━━━━━━━━━━━━━━━━━┅ Backtrace ┅━━━━━━━━━━━━━━━━━━━━╸

0: Error: no variants matched at 0x10...
╭───────────────────────┄ Thing0 ┄────────────────────┄

┆ 0: Error: failed to fill whole buffer
┆ While parsing field 'val0' in Thing0
┆ at lsf/src/main.rs:37
┆ 1: While parsing field 'self_0' in Thing::Thing0
┆ at lsf/src/main.rs:24

╰─────────────────────────────────────────────────────┄
╭───────────────────────┄ Thing1 ┄────────────────────┄

┆assertion failed: `v == 0x01` at 0x10
╰─────────────────────────────────────────────────────┄
...While parsing field 'data' in Data
at lsf/src/main.rs:21

╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
```

I think the issue is that `is_eof` looks into `EnumErrors` but doesn't test if the first is a pre-assert and the second a backtrace with an eof? I don't know if there's a more general proper way.
I reimplemented `is_eof` locally with the manual check for EnumAssert with [Assert, Backtrace that has an eof error]

Contributor guide

Open the contributing guide

Research direction

Reproduce the provided Rust example using TakeSeekExt, until_eof, and enum pre_asserts. Inspect is_eof and the EnumErrors, EnumAssert, Assert, and Backtrace error handling, focusing on EOF detection through nested enum errors. Done means the example handles the 16-byte bounded stream without reporting a spurious unmatched variant.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.