I’m going to be using Rust for quite a bit of very low-level stuff. One thing I would do in C is to directly map a section of contiguous bytes into a struct using a pointer.
For example, if I were parsing the ELF or PE header, I could just create a struct with all of the header members, load a ELF or PE file into a buffer, and then interpret the first 64 bytes of the buffer as a header struct by just moving the file pointer around by sizeof(IMAGE_DOS_HEADERS) or to move to the next header member, move the file ptr down by a WORD.
Another way would be to load it all into heap memory and index using sizeof() on that, instead of using the fp directly.
I needed to do something similar in Rust and I’m struggling to find an easy, standard way… Which was a surprise given that Rust is a systems level language. I’m aware of bincode, serde, etc… And I’ve used them in a pretty messy example… But I can’t help but wonder if there’s a simpler, more “built-in” way to just work with some raw bytes in Rust!
The C way works the same in Rust, with same caveats about alignment, endianness, and padding.
You need to add #[repr(C)] to struct definition to stop Rust compiler from optimizing the struct layout.
However, I’d try something more rusty, like the nom crate. It has examples for several binary formats. The syntax is pretty nice for a parser, and repetitions and conditionals are much nicer than struct casting alternative. It is of course safer, can even handle incomplete buffers.
You may also want to look into the scroll crate. It’s essentially a type-safe version of this *const u8 to *const Foo cast. The benefits are that it’ll avoid issues around alignment and endianness (you usually specify endianness as a parameter), but I think it works by loading each field individually so may cost you one or two more cycles than an unsafe pointer cast.