use binrw::{ io::{Cursor, Seek, SeekFrom, Write}, BinWrite, }; struct BadCrypt { inner: T, key: u8, } impl BadCrypt { fn new(inner: T) -> Self { Self { inner, key: 0 } } } impl Write for BadCrypt { fn write(&mut self, buf: &[u8]) -> binrw::io::Result { let mut w = 0; for b in buf { self.key ^= b; w += self.inner.write(&[self.key])?; } Ok(w) } fn flush(&mut self) -> binrw::io::Result<()> { self.inner.flush() } } impl Seek for BadCrypt { fn seek(&mut self, pos: SeekFrom) -> binrw::io::Result { self.inner.seek(pos) } } #[test] fn map_stream() { #[derive(BinWrite, Debug, PartialEq)] #[bw(big, magic = b"magic", map_stream = |inner| BadCrypt { inner, key: 0x80 })] struct Test(Vec); let mut out = Cursor::new(vec![]); Test(vec![0, 1, 2, 3]).write(&mut out).unwrap(); assert_eq!( out.into_inner(), &[b'm', b'a', b'g', b'i', b'c', 0x80, 0x81, 0x83, 0x80], ); } #[test] fn map_stream_field() { #[derive(BinWrite, Debug, PartialEq)] #[bw(big)] struct Test { #[bw(map_stream = BadCrypt::new)] a: Vec, #[bw(magic = b"magic", map_stream = |inner| BadCrypt { inner, key: 0x80 })] b: Vec, } let mut out = Cursor::new(vec![]); Test { a: vec![0, 1, 2, 3], b: vec![4, 5, 6, 7], } .write(&mut out) .unwrap(); assert_eq!( out.into_inner(), &[0, 1, 3, 0, b'm', b'a', b'g', b'i', b'c', 132, 129, 135, 128], ); } #[test] fn map_stream_write_with_args() { #[binrw::writer(writer)] fn adder(value: &Vec, amt: u8) -> binrw::BinResult<()> { for v in value { writer.write_all(&[*v + amt])?; } Ok(()) } #[derive(BinWrite, Debug, PartialEq)] #[bw(big)] struct Test { #[bw(map_stream = |inner| BadCrypt { inner, key: 0x80 }, write_with = adder, args(10))] a: Vec, } let mut out = Cursor::new(vec![]); Test { a: vec![0, 1, 2, 3], } .write(&mut out) .unwrap(); assert_eq!(out.into_inner(), &[138, 129, 141, 128],); }