[英]How do I serialize and deserialize a remote crate's enum as a number?
I have been trying to setup the following configuration for the serialport
crate in Rust with serde
, so I can intuitively supply 7
in my config for data_bits
, but it will be deserialized as serialport::DataBits::Seven
.我一直在试图建立了以下配置
serialport
拉斯特箱与serde
,这样我就可以直观地提供7
在我的配置为data_bits
,但将作为反序列化serialport::DataBits::Seven
。 Unfortunately, it seemingly fails the moment I want it to be a number ( 7
) and not a string ( seven
).不幸的是,当我希望它是一个数字(
7
)而不是一个字符串( seven
)时,它似乎失败了。
cargo.toml货物.toml
[package]
name = "serde_error"
version = "0.1.0"
authors = ["Jason Miller"]
edition = "2018"
[dependencies]
serialport = "3.3.0"
serde = { version = "1.0", features = ["derive"] }
ron = "0.5.1"
The following results in the error:以下结果导致错误:
6:16: Expected identifier
main.rs主文件
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
#[serde(remote = "serialport::DataBits")]
pub enum DataBitsDef {
#[serde(rename = "5")]
Five,
#[serde(rename = "6")]
Six,
#[serde(rename = "7")]
Seven,
#[serde(rename = "8")]
Eight,
}
fn default_data_bits() -> serialport::DataBits {
serialport::DataBits::Eight
}
#[derive(Debug, Serialize, Deserialize)]
pub struct TransceiverSettings {
pub vid: u16,
pub pid: u16,
pub baud_rate: u32,
#[serde(default = "default_data_bits", with = "DataBitsDef")]
pub data_bits: serialport::DataBits,
}
impl Default for TransceiverSettings {
fn default() -> Self {
Self {
vid: 0x2341,
pid: 0x0043,
baud_rate: 115_200,
data_bits: serialport::DataBits::Eight,
}
}
}
const TRX_CONFIG: &str = "
(
vid: 0x2341,
pid: 0x0043,
baud_rate: 9600,
data_bits: 7,
)
";
fn main() {
match ron::de::from_str::<TransceiverSettings>(&TRX_CONFIG) {
Err(e) => eprintln!("{}", e),
Ok(c) => println!("{:?}", c),
}
}
Oddly enough, writing 7
as seven
succeeds and returns:奇怪的是,将
7
写成seven
成功并返回:
TransceiverSettings { vid: 9025, pid: 67, baud_rate: 9600, data_bits: Seven }
main.rs主文件
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
#[serde(remote = "serialport::DataBits")]
pub enum DataBitsDef {
#[serde(rename = "5")]
Five,
#[serde(rename = "6")]
Six,
#[serde(rename = "seven")]
Seven,
#[serde(rename = "8")]
Eight,
}
fn default_data_bits() -> serialport::DataBits {
serialport::DataBits::Eight
}
#[derive(Debug, Serialize, Deserialize)]
pub struct TransceiverSettings {
pub vid: u16,
pub pid: u16,
pub baud_rate: u32,
#[serde(default = "default_data_bits", with = "DataBitsDef")]
pub data_bits: serialport::DataBits,
}
impl Default for TransceiverSettings {
fn default() -> Self {
Self {
vid: 0x2341,
pid: 0x0043,
baud_rate: 115_200,
data_bits: serialport::DataBits::Eight,
}
}
}
const TRX_CONFIG: &str = "
(
vid: 0x2341,
pid: 0x0043,
baud_rate: 9600,
data_bits: seven,
)
";
fn main() {
match ron::de::from_str::<TransceiverSettings>(&TRX_CONFIG) {
Err(e) => eprintln!("{}", e),
Ok(c) => println!("{:?}", c),
}
}
One of the given examples in the serde
documentation seems relevant to my case, but I haven't managed to get it working with my setup. serde
文档中给定的示例之一似乎与我的案例有关,但我还没有设法让它与我的设置一起工作。
Serialize enum as number
将枚举序列化为数字
Theserde_repr
crate provides alternative derive macros that derive the same Serialize and Deserialize traits but delegate to the underlying representation of a C-like enum.serde_repr
crate 提供替代派生宏,派生相同的 Serialize 和 Deserialize 特征,但委托给类 C 枚举的底层表示。 This allows C-like enums to be formatted as integers rather than strings in JSON这允许类似 C 的枚举被格式化为整数而不是 JSON 中的字符串
#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)] #[repr(u8)] enum SmallPrime { Two = 2, Three = 3, Five = 5, Seven = 7, }
Support for #[serde(remote)]
is not present in serde_repr 0.1.5. serde_repr 0.1.5 中不支持
#[serde(remote)]
。 You will need to submit a pull request or issue to add support for it.您需要提交拉取请求或问题以添加对它的支持。
Instead, follow the advice in How to transform fields during deserialization using Serde?相反,请遵循如何在使用 Serde 进行反序列化期间转换字段中的建议? and How to transform fields during serialization using Serde?
以及如何使用 Serde 在序列化期间转换字段? :
:
use serde::{Deserialize, Serialize};
mod shim {
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
use serialport::DataBits;
pub fn serialize<S>(v: &DataBits, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use DataBits::*;
let v: u8 = match v {
Five => 5,
Six => 6,
Seven => 7,
Eight => 8,
};
v.serialize(s)
}
pub fn deserialize<'de, D>(d: D) -> Result<DataBits, D::Error>
where
D: Deserializer<'de>,
{
use DataBits::*;
match u8::deserialize(d)? {
5 => Ok(Five),
6 => Ok(Six),
7 => Ok(Seven),
8 => Ok(Eight),
o => Err(D::Error::custom(format_args!("Invalid value {}", o))),
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct TransceiverSettings {
pub vid: u16,
pub pid: u16,
pub baud_rate: u32,
#[serde(default = "default_data_bits", with = "shim")]
pub data_bits: serialport::DataBits,
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.