我有一个类似于下面的枚举:

#[derive(Deserialize)]
enum ExampleEnum {
    #[serde(rename = "variant1-rename")]
    Variant1,
    #[serde(rename = "variant2-rename")]
    Variant2,
    Other(String),
}

它应该像这样反序列化:

Serialized Deserialized
"variant1-rename" ExampleEnum::Variant1
"variant2-rename" ExampleEnum::Variant2
"foobar" ExampleEnum::Other("foobar")

在我当前的代码中,前两个代码按预期工作,但最后一个没有,程序错误地指出它应该是"varant1-rename"、"varant2-rename"或"ther".

#[serde(other)]属性似乎会产生所需的行为,但它只能与内部标记或相邻标记的枚举一起使用.

我要反序列化的(JSON)数据有一个应该反序列化为枚举的属性,因此它将如下所示:

{
    "property": "variant1-rename"
}

推荐答案

以下是我的解决问题的代码,基于serde文档中的Caesar's answer页和Manually implementing Deserialize for a struct页.

use serde::{ Deserialize, de };

impl<'de> Deserialize<'de> for ExampleEnum {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        struct ExampleEnumVisitor;

        impl<'de> de::Visitor<'de> for ExampleEnumVisitor {
            type Value = ExampleEnum;

            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
                formatter.write_str("`variant1-rename`, `variant2-rename`, or some other string")
            }

            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
            where
                E: de::Error,
            {
                match v {
                    "variant1-rename" => Ok(ExampleEnum::Variant1),
                    "variant2-rename" => Ok(ExampleEnum::Variant2),
                    _ => Ok(ExampleEnum::Other(v.to_string())),
                }
            }
        }

        deserializer.deserialize_identifier(ExampleEnumVisitor)
    }
}

如果您想要更短的解决方案,请使用Caesar's.阅读他们的解决方案下面的 comments ,以了解其中的差异.

Rust相关问答推荐

重新导出proc宏导致未解决的extern crate错误""

在一个tauri协议处理程序中调用一个rectuc函数的推荐技术是什么?

为什么BitVec缺少Serialize trait?

具有对同一类型的另一个实例的可变引用的

如何提高自定义迭代器的`extend`性能

如何点击()迭代器?

`*mut[T]`与`*mut T`的区别

完全匹配包含大小写的整数范围(&Q;)

为什么Option类型try块需要类型注释?

根据填充系数以相对大小在给定空间中布局项目

在什么情况下 `..._or()` 比 `..._or_else(|| {})` 更好,为什么?

我应该如何表达具有生命周期参数的类型的总排序,同时允许与不同生命周期进行比较?

std mpsc 发送者通道在闭包中使用时关闭

在多核嵌入式 Rust 中,我可以使用静态 mut 进行单向数据共享吗?

如何判断服务器是否正确接收数据

使用 rust 在 google cloud run (docker) 中访问环境变量的适当方法

试图理解 Rust 中的可变闭包

使用 HashMap 条目时如何避免字符串键的短暂克隆?

为什么这个闭包没有比 var 长寿?

如果我立即等待,为什么 `tokio::spawn` 需要一个 `'static` 生命周期?