我有一个像下面这样的枚举
#[serde(rename_all="snake_case")]
pub enum Flag {
One,
Two,
Three { value: Option<Decimal>}
}
我想匹配以下 JSON 表示形式
{"flag":"one"} // Working fine
{"flag":"two"} // Working fine
{"flag":{"three":{"value":###}} // Working fine -> Three { value: Some(###) }
{"flag":"three"} // not working, desired result -> Three { value: None }
我怎样才能得到这样的行为?
我已经尝试过了:
#[serde(default)]
在变体上,但这只会匹配{"flag":{"three":{}}}
#[serde(untagged)]
在变体上,但这适用于完整枚举ThreeNone
具有#[serde(rename="Three")]
属性的另一种变体
请帮忙
假设您想要原样
Flag
,而不对enum
及其变体进行任何更改。那么由于 JSON 的结构,这会变得有点棘手。当我遇到这些简单与复杂形式的 JSON 数据时,我通常会将其实现为多种类型。总体而言
serde(untagged)
enum
。注意:变体的顺序很重要
serde(untagged)
,因为 serde 将按顺序尝试变体,并在成功反序列化时停止。为了保持原样
Flag
,您可以使用serde(from = ...)
或通过其他类型serde(try_from ...)
进行反序列化。其他类型也可以保持私密。为了演示目的,我已将您的 改为
Decimal
。u32
但只要Decimal
实现Deserialize
,那么它们就可以互换。它看起来像这样:
那么我们需要的是
From<ComplexFlag> for Flag
:使用下列方法测试它:
然后正确得出:
或者,您也可以手动
Deserialize
实现Flag
:但这可能看起来更像黑客,更难维护。与中的重复代码
SimpleFlag
和手动From<ComplexFlag> for Flag
实现相比。