bincode-org / bincode

A binary encoder / decoder implementation in Rust.
MIT License
2.69k stars 272 forks source link

Feature Request: Enums as number #669

Closed bkolligs closed 1 year ago

bkolligs commented 1 year ago

I'd like to be able to do this:

#[derive(Encode)]
#[repr(u8)]
enum MessageType {
    One,
    Two,
    Three,
    Four,
}

assert_eq!(bincode::serialize(&MessageType::One).unwrap(), &[1]);
assert_eq!(bincode::serialize(&MessageType::Two).unwrap(), &[2]);
assert_eq!(bincode::serialize(&MessageType::Three).unwrap(), &[3]);
assert_eq!(bincode::serialize(&MessageType::Four).unwrap(), &[4]);

This is often required when interfacing with any C code or operating system level data, which is most of what I have been using bincode for. I know there is https://github.com/dtolnay/serde-repr, but it'd be nice if this worked with the new Encode, Decode traits.

VictorKoenders commented 1 year ago

https://github.com/bincode-org/bincode#why-does-bincode-not-respect-repru8

Why does bincode not respect #[repr(u8)]?

Bincode will encode enum variants as a u32. If you're worried about storage size, we can recommend enabling Configuration::with_variable_int_encoding(). This option is enabled by default with the standard configuration. In this case enum variants will almost always be encoded as a u8.

Currently we have not found a compelling case to respect #[repr(...)]. You're most likely trying to interop with a format that is similar-but-not-quite-bincode. We only support our own protocol (spec).

If you really want to use bincode to encode/decode a different protocol, consider implementing Encode and Decode yourself. bincode-derive will output the generated implementation in target/generated/bincode/<name>_Encode.rs and target/generated/bincode/<name>_Decode.rs which should get you started.