Curious if Debug can removed? #287
-
I have a protocol that uses big endian for a few of the u16 bytes. So, it works perfectly with read_be(), nice! But I have to layout the deserialization kinda funky like to match the BE: use bitfield_struct::bitfield;
use binrw::{BinRead, BinReaderExt};
#[bitfield(u64)]
#[derive(BinRead)]
struct Header {
command_id: u8,
sequence: u8,
group_id: u16,
length: u16,
flags: u8,
#[bits[3]]
op: u8,
#[bits[2]]
version: u8,
#[bits[3]]
_reserved: u8,
}
fn main() {
const DATA: [u8; 8] = [0x01 | (2 << 3), 3, 0, 4, 0, 5, 6, 7];
let mut reader = std::io::Cursor::new(&DATA);
let header: Header = reader.read_be().unwrap();
println!("{:?}", header);
} This will run with output:
Great! Except that the debug ordering is also "the wrong order", and I didn't even specify that I wanted to derive Debug! I'd love to override the Debug trait, but this seems to not be a thing in Rust? impl std::fmt::Debug for Header {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Header {{ op: {}, version: {}, flags: {}, length: {}, group_id: {}, sequence: {}, command_id: {} }}",
self.op(),
self.version(),
self.flags(),
self.length(),
self.group_id(),
self.sequence(),
self.command_id()
)
}
} Gives diagnostic
Perhaps the Debug trait can be removed from bitfield so that people can define their own Debug if needed? Maybe there is a better way, I am very new to Rust! Also, I think it's been addressed that the struct layout occurs in LE or BE order as a design decision. I can understand that. But it will cause protocols like this to be "backwards" of the spec since these sorts of protocols are not usually "written backwards" just because they use BE for some of their integers! Something like this would match how Python and C would do it, for example: #[bitfield(u64)]
#[derive(BinRead)]
struct Header {
#[bits[3]]
op: u8,
#[bits[2]]
version: u8,
#[bits[3]]
_reserved: u8,
flags: u8,
#[endian[big]]
length: u16,
#[endian[big]]
group_id: u16,
sequence: u8,
command_id: u8,
} And then the reader would use Thanks for this great work! JP |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments
-
Another thought - am I bringing this on myself by using u64? |
Beta Was this translation helpful? Give feedback.
-
Agh! Debug is resolved easily with use bitfield_struct::bitfield;
use binrw::{BinRead, BinReaderExt};
#[bitfield[u64, debug = false]]
#[derive(BinRead)]
struct Header {
command_id: u8,
sequence: u8,
group_id: u16,
length: u16,
flags: u8,
#[bits[3]]
op: u8,
#[bits[2]]
version: u8,
#[bits[3]]
_reserved: u8,
}
impl std::fmt::Debug for Header {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Header {{ op: {}, version: {}, flags: {}, length: {}, group_id: {}, sequence: {}, command_id: {} }}",
self.op(),
self.version(),
self.flags(),
self.length(),
self.group_id(),
self.sequence(),
self.command_id()
)
}
}
fn main() {
const DATA: [u8; 8] = [0x01 | (2 << 3), 3, 0, 4, 0, 5, 6, 7];
let mut reader = std::io::Cursor::new(&DATA);
let header: Header = reader.read_be().unwrap();
println!("{:?}", header);
}
🚀 |
Beta Was this translation helpful? Give feedback.
-
The funny thing about the way people throw BE and LE around, is that the commonly only think about the byte order of INDIVIDUAL integers, not the byte order of the entire structure. I believe this implementation is correct in considering it to be the byte order of the overall structure. |
Beta Was this translation helpful? Give feedback.
-
Sorry for the delay. Just to be clear, binrw doesn’t add a |
Beta Was this translation helpful? Give feedback.
Agh! Debug is resolved easily with
#[bitfield[u64, debug = false]]