binwrite
binwrite copied to clipboard
derive macro silently fails when ran on a tuple struct
Apologies, this isn't exactly a minimal test, just how I discovered it.
use binread::{BinRead, NullString};
use binwrite::BinWrite;
// this *compiles* but does not behave as exepected.
#[derive(BinRead, BinWrite, Clone, PartialEq, Default)]
pub struct BadNullString(
#[binwrite(cstr, preprocessor(NullString::to_string))]
NullString
);
#[test]
fn test_bad() {
let test = BadNullString(NullString(Vec::from(&b"Test!"[..])));
let expected = Vec::from(&b"Test!\0"[..]);
let mut writer = std::io::Cursor::new(Vec::new());
test.write(&mut writer).unwrap();
let res = writer.into_inner();
assert_eq!(res, expected); // fails, res has no bytes in it
}
// this works correctly
#[derive(BinRead, BinWrite, Clone, PartialEq, Default)]
pub struct GoodNullString {
#[binwrite(cstr, preprocessor(NullString::to_string))]
inner: NullString
}
#[test]
fn test_good() {
let test = GoodNullString { inner: NullString(Vec::from(&b"Test!"[..])) };
let expected = Vec::from(&b"Test!\0"[..]);
let mut writer = std::io::Cursor::new(Vec::new());
test.write(&mut writer).unwrap();
let res = writer.into_inner();
assert_eq!(res, expected); // passes
}
Minimal reproduction:
use binread::{BinRead, NullString};
use binwrite::BinWrite;
#[derive(BinWrite)]
struct Bad(u32);
// #[derive(BinWrite)]
// struct Good {
// inner: u32
// }
#[test]
fn test_bad() {
let mut writer = std::io::Cursor::new(Vec::new());
Bad(0x01020304u32).write(&mut writer);
// Good {inner: 0x01020304}.write(&mut writer);
assert_eq!(writer.into_inner(), vec![4, 3, 2, 1]); // fails because no bytes were written!
}
The macro expansion looks like this:
struct Bad(u32);
impl ::binwrite::BinWrite for Bad {
fn write_options<W: ::std::io::Write>(
&self,
writer: &mut W,
options: &::binwrite::WriterOption,
) -> ::std::io::Result<()> {
let mut _writer = ::binwrite::write_track::WriteTrack::new(writer);
let writer = &mut _writer;
// note that no writing is occurring here!
Ok(())
}
}