jam1garner / jam1garner/binrw

Add serde-style `brw(with)` attribute

Open
#98 0 comments 1 reaction 0 assignees View on GitHub
enhancement
Dominant language
Rust
Stars
853
Forks
56
PR merge metrics
No merged PRs in 30d

Description

General idea is providing a module containing both a custom parser and a custom writer function. This would also make it easier to make binrw compatibility crates by allowing you to two generic functions that are custom readers/writers for all types the crate supports to get around orphan rules:

In the compatibility crate (let's call it `binrw_3d`, similar to bevy-style 3rd party compatibility crates, basically a binrw crate with common 3d type parsers):
```rust
use binrw::{prelude::*, io::*};

trait Supported {
type ReprType: Into + From + BinRead + BinWrite;
}

fn read_options(reader: &mut R, opts: &ReadOptions, args: ::Args) -> BinResult {
::read_options(reader, opts, args)
}

fn write_options(
val: &T,
writer: &mut W,
options: &WriteOptions,
args: ::Args,
) -> BinResult<()> {
::write_options(&T::ReprType::from(val), writer, opts)
}
```

Then for each type that should be supported, make a new struct implement `BinRead`/`BinWrite` as normal, and implement conversion to and from the type itself. Then all that's needed is:

```rust
impl Supported for glam::Vec3 {
type Repr = MyVec3f; // MyVec3f implements BinRead/BinWrite/From/Into
}
```

And while that's a bit of boilerplate just to make a binrw implementation for a foreign type, all that your crate user needs to do is:

```rust
use glam::Vec3;

#[binrw]
struct Vertex {
#[brw(with = binrw_3d)]
position: Vec3,

#[brw(with = binrw_3d)]
position: Quaternion,
}
```

and the foreign types "just work"

### Open Design Questions

Should binrw provide a macro or two to make all the boilerplate above just a single line? Is encouraging 3rd-party utility types worthwhile enough for that? Maybe something like:

```rust
use binrw::*;

binrw::conversion_crate!(Supported);

#[binrw(Supported for glam::Vec3)]
struct Vec3 {
x: f32,
y: f32,
z: f32,
}

// impl conversion traits here
```

Contributor guide

Open the contributing guide

Research direction

No source files or tests are named. Start by reviewing the proposed #[brw(with = ...)] usage and the compatibility-crate example, then resolve whether a generic reader/writer module is sufficient and whether macros should reduce the boilerplate. Done means an agreed design and an implementation path for foreign-type BinRead/BinWrite compatibility.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.