Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add serde-style brw(with) attribute #98

Open
jam1garner opened this issue Feb 19, 2022 · 0 comments
Open

Add serde-style brw(with) attribute #98

jam1garner opened this issue Feb 19, 2022 · 0 comments
Labels
enhancement New feature or request

Comments

@jam1garner
Copy link
Owner

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):

use binrw::{prelude::*, io::*};

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

fn read_options<R: Read + Seek, T: Supported>(reader: &mut R, opts: &ReadOptions, args: <T::ReprType as BinRead>::Args) -> BinResult<T> {
    <T::ReprType as BinRead>::read_options(reader, opts, args)
}

fn write_options<W: Write + Seek, T: Supported>(
    val: &T,
    writer: &mut W,
    options: &WriteOptions,
    args: <T::ReprType as BinWrite>::Args,
) -> BinResult<()> {
    <T::ReprType as BinWrite>::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:

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

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:

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:

use binrw::*;

binrw::conversion_crate!(Supported);

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

// impl conversion traits here
csnover added a commit to csnover/binrw that referenced this issue Nov 7, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 11, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 12, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 12, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 13, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 13, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 13, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 14, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 15, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 15, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 15, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 15, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 15, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 15, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 15, 2022
@csnover csnover self-assigned this Nov 16, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 16, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 16, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 16, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 17, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 17, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 21, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 21, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 21, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 25, 2022
csnover added a commit to csnover/binrw that referenced this issue Nov 26, 2022
@csnover csnover removed their assignment May 9, 2023
@csnover csnover added the enhancement New feature or request label Sep 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants