gpt4 book ai didi

rust - 如何将远程 crate 的枚举序列化和反序列化为数字?

转载 作者:行者123 更新时间:2023-12-04 19:46:22 25 4
gpt4 key购买 nike

我一直在尝试为 serialport 设置以下配置用 serde 在 Rust 中装箱,因此我可以直观地在我的配置中为 data_bits 提供 7,但它将被反序列化为 serialport::DataBits::Seven。不幸的是,当我希望它是一个数字 (7) 而不是一个字符串 (seven) 时,它似乎失败了。

测试用例

cargo.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"

错误结果如下:

6:16: Expected identifier

ma​​in.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),
}
}

奇怪的是,将7写成seven成功并返回:

TransceiverSettings { vid: 9025, pid: 67, baud_rate: 9600, data_bits: Seven }

ma​​in.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),
}
}

服务代表

serde 中给定的示例之一 documentation似乎与我的情况相关,但我还没有设法让它与我的设置一起工作。

Serialize enum as number
The serde_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. This allows C-like enums to be formatted as integers rather than strings in JSON

#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
#[repr(u8)]
enum SmallPrime {
Two = 2,
Three = 3,
Five = 5,
Seven = 7,
}

最佳答案

#[serde(remote)] 的支持是not present在 serde_repr 0.1.5 中。您将需要提交拉取请求或问题以添加对其的支持。

相反,请遵循 How to transform fields during deserialization using Serde? 中的建议和 How to transform fields during serialization using 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,
}

关于rust - 如何将远程 crate 的枚举序列化和反序列化为数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60067586/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com