我有一个 JSON API,它返回一个如下所示的对象:
{
"PrivatePort": 2222,
"PublicPort": 3333,
"Type": "tcp"
}
为了捕获这个,我有一个枚举和一个结构:
#[derive(Eq, PartialEq, Deserialize, Serialize, Debug)]
#[serde(rename_all = "snake_case")]
pub enum PortType {
Sctp,
Tcp,
Udp,
}
#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "PascalCase")]
pub struct PortMapping {
pub private_port: u16,
pub public_port: u16,
#[serde(rename = "Type")]
pub port_type: PortType,
}
目前,此 API 仅支持 PortType
中列出的三种协议(protocol),但我们假设将来会添加对 DCCP
的支持。我不希望 API 的客户端仅仅因为他们可能没有查看的配置选项中的未知字符串而开始失败。
为了解决这个问题,我添加了一个 Unknown
变体和一个 String
来表示值:
#[derive(Eq, PartialEq, Deserialize, Serialize, Debug)]
#[serde(rename_all = "snake_case")]
pub enum PortType {
Sctp,
Tcp,
Udp,
Unknown(String),
}
这里的目标是在传入未知值时以稍微不方便的 PortType::Unknown("dccp")
值结束。当然,这不是我想要的就像开箱即用——传递未知的 "dccp"
值将导致:
Error("unknown variant `dccp`, expected one of `sctp`, `tcp`, `udp`, `unknown`", line: 1, column: 55)
是否有 Serde 配置可以满足我的需求,或者我应该为 PortType
手动编写 Deserialize
和 Serialize
实现?
最佳答案
这有一个问题,虽然它已经开放了 3 年,但到目前为止还没有完全解决。 Serde #912 .
在发表这篇文章时,目前正在实现的(虽然未记录)是 #[serde(other)]
。它只能应用于单位枚举字段,这限制了它的用处:
#[derive(Deserialize, PartialEq)]
#[serde(tag = "tag")]
enum Target {
A(()),
B(()),
#[serde(other)]
Others
}
fn main() {
assert_eq!(Target::Others, from_str::<Target>(r#"{ "tag": "blablah" }"#).unwrap());
}
除此之外,在撰写本文时唯一的其他方法是编写您自己的Deserialize
实现。
关于rust - 我如何支持 Serde 枚举的未知值或其他值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57469527/