当显式枚举值不匹配时,如何将枚举压缩为特殊情况?

3
我希望在未知情况下,与上一案例相关联。
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(untagged)]
pub enum Action {
    Action1,
    Action2,
    Action3,
    Other(String), // when not known it should be here
}

我尝试使用指令

#[serde(untagged)]

但它无法正确序列化。

let b = Action::Action1;
let s = serde_json::to_string(&b);
let ss = s.unwrap();
println!("ss {:#?}", &ss);
let val = serde_json::to_value(b);
println!("ss {:#?}", &val);

导致
ss "null"
ss Ok(
    Null,
)

Playground链接


我认为你需要进行自定义实现,我不认为在serde中有一种构建方式可以做到这一点。 - Stargateur
1
唯一接近的是 https://serde.rs/variant-attrs.html#other - Stargateur
我尝试过了,但是当情况为Other(String)时它无法编译,如果是Other(没有关联值)则可以编译。 - Avba
错误:#[serde(other)] 必须在单元变体上。 - Avba
我并没有说它会做你想要的事情,我只是说它是最接近你想要的东西。 - Stargateur
1个回答

0

我能想到两个相互关联的选项。

首先使用 From 将其转换为字符串,每次序列化时再使用 From 将其转换回你自己的类型。这需要你在序列化和反序列化时每次进行转换,但可以实现你的目标。

如果你想以更多的工作量来使 API 更加清晰,可以自己实现序列化和反序列化。以下是一些参考资料:

  1. 自定义序列化
  2. 实现 Serialize
  3. 实现 Deserialize

作为第二个选项,如果你愿意添加另一个依赖项 serde_with, 你可以将自定义序列化和反序列化外包。

根据它的文档:

使用 Display 和 FromStr 特性对类型进行序列化/反序列化,例如 u8、url::Url 或 mime::Mime。有关详细信息,请查看 DisplayFromStr 或 serde_with::rust::display_fromstr。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接