Skip to content

Commit

Permalink
Move array parsing to use const generics
Browse files Browse the repository at this point in the history
* Implement `BinRead` for all array lengths using const generics.
* Fix array initialization via `MaybeUninit`.
* Restore the old code and put the new one behind a feature gate.
* Use the array-init crate over manual unsafe initialization.

Ported from jam1garner/binread#41
  • Loading branch information
ColinFinck authored and jam1garner committed Mar 28, 2021
1 parent e055ab6 commit e80c8f8
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 28 deletions.
1 change: 1 addition & 0 deletions binrw/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ documentation = "https://docs.rs/binrw"

[dependencies]
binrw_derive = { version = "0.2.0", path = "../binrw_derive" }
array-init = { version = "1.1" }

[dev-dependencies]
modular-bitfield = "0.9"
Expand Down
47 changes: 19 additions & 28 deletions binrw/src/binread_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,39 +116,30 @@ impl<B: BinRead> BinRead for Vec<B> {
}
}

macro_rules! binread_array_impl {
($($size:literal),*$(,)?) => {
$(
impl<B: BinRead + Default> BinRead for [B; $size] {
type Args = B::Args;

fn read_options<R: Read + Seek>(reader: &mut R, options: &ReadOptions, args: Self::Args) -> BinResult<Self> {
let mut arr: [B; $size] = Default::default();
for elem in arr.iter_mut() {
*elem = BinRead::read_options(reader, options, args.clone())?;
}
Ok(arr)
}
impl<C: Copy + 'static, B: BinRead<Args = C>, const N: usize> BinRead for [B; N] {

This comment has been minimized.

Copy link
@csnover

csnover Mar 28, 2021

Collaborator

This Copy constraint is not necessary, is it? (Should be cloning the args.)

type Args = B::Args;

fn after_parse<R>(&mut self, reader: &mut R, ro: &ReadOptions, args: Self::Args)-> BinResult<()>
where R: Read + Seek,
{
for val in self.iter_mut() {
val.after_parse(reader, ro, args.clone())?;
}
fn read_options<R: Read + Seek>(
reader: &mut R,
options: &ReadOptions,
args: Self::Args,
) -> BinResult<Self> {
let arr = array_init::try_array_init(|_| BinRead::read_options(reader, options, args))?;
Ok(arr)
}

Ok(())
}
}
)*
fn after_parse<R>(&mut self, reader: &mut R, ro: &ReadOptions, args: B::Args) -> BinResult<()>
where
R: Read + Seek,
{
for val in self.iter_mut() {
val.after_parse(reader, ro, args)?;
}

Ok(())
}
}

binread_array_impl!(
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32
);

macro_rules! binread_tuple_impl {
($type1:ident $(, $types:ident)*) => {
#[allow(non_camel_case_types)]
Expand Down

0 comments on commit e80c8f8

Please sign in to comment.