I'm fairly new to Rust and am using bincode in my project. The encoding of enum variants is an issue that I've been trying to deal with as I am interfacing with an existing server. The old project was written in C and the compilier option of "fshort-enums" was defined.
In the old C project I would define an enum something like:
enum test_enum {
Start,
Init,
Complete,
}
and then when this data was put into the packet it would take up 1 byte like this:
0x00,
0x01,
0x02
If I defined the enum as:
enum test_enum {
Start,
Init,
Complete = 65535,
}
then when this data was put into the packet every variant would take up 2 bytes like this:
0x00 0x00,
0x01 0x00,
0x02 0x00
Now I've found a way to configure bincode
enum encoding to change from the default 4 bytes to be the appropriate size for the value like this:
#[derive(Serialize, Deserialize)]
enum TestEnum {
Start,
Init,
Complete = 65535,
}
let x = TestEnum::Complete;
if let Ok(bytes) = bincode::options().with_varint_encoding().serialize(&x) {
println!("{:?}", bytes); // [2]
}
Question1: How do I force bincode
to make all variants take up 2 bytes?
Question2: How do I force bincode
to apply the enum variant value? (in this example TestEnum::Complete
has a value of 2 instead of 65535).
Options::with_varint_encoding
is probably not what you want, since it will only use 1 byte for integers that are less than 256. You can useOptions::with_fixint_encoding
to encode integers with the same precision as their Rust type, but you don't need to specify it, as it is the default already.Serde is structural; it doesn't really care about how the data is actually represented in memory. The numerical values you assigned to the enum are lost and
bincode
will only see the names of the variants.You can solve this by configuring
serde
to convert your enum into an integer before exposing it to thebincode
serializer:Then your code gives the expected result: