如何用enum反序列化字符串,其中任何其他值反序列化为新类型变体,同时保留字符串?



我有一个类似于下面的enum:

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

它应该像这样反序列化:

tbody> <<tr>"variant2-rename"
序列化反序列化
"variant1-rename"ExampleEnum::Variant1ExampleEnum::Variant2
"foobar"ExampleEnum::Other("foobar")

除了打开一个功能请求服务器,我认为唯一的方法是手动实现Deserialize:

#[derive(Debug)]
enum ExampleEnum {
Variant1,
Variant2,
Other(String),
}
impl<'de> Deserialize<'de> for ExampleEnum {
fn deserialize<D>(de: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let variant = String::deserialize(de)?;
Ok(match variant.as_str() {
"variant1-rename" => ExampleEnum::Variant1,
"variant2-rename" => ExampleEnum::Variant2,
_other => ExampleEnum::Other(variant),
})
}
}

如果你没有重命名所有的变量,你可能会让enum_derive::FromStr更流畅一些。

这是我解决这个问题的代码,基于Caesar的答案和serde文档中的手动实现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)
}
}

如果你想要一个更短的解决方案,使用凯撒的。阅读他们的解决方案下的评论,了解差异。

相关内容

  • 没有找到相关文章

最新更新