Serialization Rust二进制代码枚举二进制序列化

Serialization Rust二进制代码枚举二进制序列化,serialization,enums,rust,bincode,Serialization,Enums,Rust,Bincode,我是个新手,在我的项目中使用bincode。枚举变量的编码是我在与现有服务器交互时一直试图解决的一个问题。旧项目是用C编写的,并且定义了编译器选项“fshortenums” 在旧的C项目中,我将定义一个枚举,类似于: enum测试\u enum{ 开始 初始化, 完成 } 然后,当这些数据被放入数据包时,它将占用1个字节,如下所示: 0x00, 0x01, 0x02 如果我将枚举定义为: enum测试\u enum{ 开始 初始化, 完成=65535, } 然后,当将此数据放入数据包时,每

我是个新手,在我的项目中使用bincode。枚举变量的编码是我在与现有服务器交互时一直试图解决的一个问题。旧项目是用C编写的,并且定义了编译器选项“fshortenums”

在旧的C项目中,我将定义一个枚举,类似于:

enum测试\u enum{
开始
初始化,
完成
}
然后,当这些数据被放入数据包时,它将占用1个字节,如下所示:

0x00,
0x01,
0x02
如果我将枚举定义为:

enum测试\u enum{
开始
初始化,
完成=65535,
}
然后,当将此数据放入数据包时,每个变量将占用2个字节,如下所示:

0x00 0x00,
0x01 0x00,
0x02 0x00
现在,我找到了一种配置
bincode
enum编码的方法,可以将默认的4字节更改为适合以下值的大小:

#[派生(序列化、反序列化)]
测试枚举{
开始
初始化,
完成=65535,
}
设x=TestEnum::Complete;
如果让Ok(字节)=bincode::options(){
println!(“{:?}”,字节);//[2]
}
问题1:如何强制
bincode
使所有变体占用2个字节


问题2:如何强制
bincode
应用枚举变量值?(在本例中,
TestEnum::Complete
的值为2,而不是65535)。

选项::with_varint_encoding
可能不是您想要的,因为对于小于256的整数,它只使用1个字节。您可以使用
Options::with_fixint_encoding
对整数进行编码,编码精度与它们的Rust类型相同,但不需要指定它,因为它已经是默认值

Serde是结构性的;它实际上并不关心数据在内存中的实际表示方式。分配给枚举的数值将丢失,
bincode
将只看到变量的名称

您可以通过配置
serde
将枚举转换为整数,然后再将其公开给
bincode
序列化程序来解决此问题:

#[derive(Serialize, Deserialize, Copy, Clone)]
#[serde(into = "u16")]
enum TestEnum {
    Start,
    Init,
    Complete = 65535,
}

impl From<TestEnum> for u16 {
    fn from(value: TestEnum) -> u16 {
        value as u16
    }
}

我确实使用了@Peter Hall提供的答案,但我必须为所有已定义的枚举(有很多)添加一个实现,以便能够序列化它们,并添加第二个实现,以便能够反序列化。所以我继续调查,找到了一个对我来说更有用的替代方案。我现在使用crates.io中的板条箱并向枚举添加一些属性,而不是为每个枚举添加一个实现。因此,代码如下所示:

use num_enum::{IntoPrimitive, TryFromPrimitive};

#[derive(Serialize, Deserialize, Copy, Clone)]
#[serde(into = "u16", try_from = "u16")]
#[repr(u16)]
enum TestEnum {
    Start,
    Init,
    Complete = 65535,
}

我只是认为这可能会在将来帮助其他人。

bincode的目的是为您处理这一点,您无法配置这些。非常感谢您的帮助。我刚刚试过这个,它完全符合我的需要。非常感谢!
use num_enum::{IntoPrimitive, TryFromPrimitive};

#[derive(Serialize, Deserialize, Copy, Clone)]
#[serde(into = "u16", try_from = "u16")]
#[repr(u16)]
enum TestEnum {
    Start,
    Init,
    Complete = 65535,
}