Men*_*ndy 13 rust serde serde-json
我正在尝试获取枚举变体的名称,作为字符串 serde 期望/创建的名称。例如,假设我有以下枚举:
#[derive(Serialize, Deserialize)]
#[serde(rename_all="camelCase")]
pub enum SomeEnum {
WithoutValue,
withValue(i32),
}
Run Code Online (Sandbox Code Playgroud)
那么我怎样才能获得变体的 serde 名称呢?就像是
serde::key_name(SomeEnum::WithoutValue) // should be `withoutValue`
serde::key_name(SomeEnum::WithValue) // should be `withValue`
Run Code Online (Sandbox Code Playgroud)
serde_json对于没有值的变体,我可以使用 , 进行黑客攻击:
serde_json::to_string(SomeEnum::WithoutValue).unwrap(); // yields `"withoutValue"` with quotation marks
Run Code Online (Sandbox Code Playgroud)
这不是最好的解决方案,因为我需要去掉引号,但在技术上可以工作。
更糟糕的是当枚举变量具有值时。它变得更加混乱。
serde_json::to_string(SomeEnum::WithValue(0)).unwrap(); // yields `"{\"second\":0}"
Run Code Online (Sandbox Code Playgroud)
有没有一种干净的方法来实现这一目标?我找不到 serde API 来获取字符串形式的键名。
提取变体信息的一种稳定但有点样板的方法是实现Serializer从函数中收集变体名称的自定义serialize_*_variant。
这是 所采取的方法serde_variant。@Mendy 提到这个箱子仅适用于单位变体。这是自述文件中的示例。
use serde_variant::to_variant_name;
#[derive(Serialize)]
enum Foo {
Var1,
#[serde(rename = "VAR2")]
Var2,
}
assert_eq!(to_variant_name(&Foo::Var1).unwrap(), "Var1");
assert_eq!(to_variant_name(&Foo::Var2).unwrap(), "VAR2");
Run Code Online (Sandbox Code Playgroud)
另一个需要提到的缺点是,这仅适用于默认的外部标记枚举表示。其他表示不使用这些serialize_*_variant函数。