jam1garner / binrw

A Rust crate for helping parse and rebuild binary data using ✨macro magic✨.
https://binrw.rs
MIT License
545 stars 35 forks source link

Handle unknown enum variant magics as not-errors #233

Closed micolous closed 8 months ago

micolous commented 8 months ago

I'm trying to implement serialisation and deserialisation for a binary protocol using binrw, which has Messages and Commands which look a bit like like this:

struct Message {
  len: u16, // of Message
  commands: Vec<Command>, // Message contains 1..n Command(s)
}

struct Command {
  len: u16, // of the entire Command
  _padding: u16, // because C++
  id: [u8; 4], // or magic
  payload: Vec<u8>, // (len - 8) bytes, command-specific options
}

My current (non-binrw) implementation maps Command into an enum like this:

struct MessageAsPayloads {
  payloads: Vec<Payload>,
}

enum Payload {
  // Command::id = b"Alph"
  Alpha(AlphaOpts),
  // Command::id = b"Brav"
  Bravo(BravoOpts),
  // Command types we don't know become an Unknown variant
  Unknown(id: [u8; 4], payload: Vec<u8>),
}

I haven't implemented all of the protocol (it's a slow process of reverse engineering, and there are a lot of command types), so I'd like the parser to just ignore things that aren't implemented yet by pushing them to an "Unknown" variant.

It looks like binrw's treatment of Enums uses a magic too (which I can provide!), but it would return an error if parsing a Message (top-level) because of return_all_errors, and return_unexpected_error would cause it to give a NoVariantMatch.

Is there a nice way handle unknown variants with binrw's derive macros?