当枚举值不匹配时,我该如何反序列化枚举?

28

我有一个JSON结构,看起来像这样:

{ "type": "suite", "event": "started", "test_count": 1 }

我想要将数据反序列化为这些结构体:

#[derive(Debug, Deserialize)]
enum ResultType {
    Suite,
    Test,
}

#[derive(Debug, Deserialize)]
enum ResultEvent {
    Started,
    Failed,
    Ok,
}

#[derive(Debug, Deserialize)]
struct JsonResult {
    #[serde(rename(deserialize = "type"))]
    test_type: ResultType,
    event: ResultEvent,
    test_count: Option<u32>,
}

我找不到一种方法来使serde_json使用正确的大小写。我一直在收到这些错误:

Error("unknown variant `suite`, expected `Suite` or `Test`", line: 1, column: 17)
如果我将枚举值的大小写更改为全小写或全大写,它可以工作,但我想使用PascalCase。
3个回答

49

您只需要在枚举定义之前添加 #[serde(rename_all = "snake_case")] 即可。

其他可能的值包括lowercase, UPPERCASE, PascalCase, camelCase, snake_case, SCREAMING_SNAKE_CASE, kebab-caseSCREAMING-KEBAB-CASE


3
我需要小写字母,但这确实是解决方法!谢谢! - CaseyB

7

如果您想支持不同的大小写,可以在枚举变体上添加alias

enum ResultType {
    #[serde(alias="suite", alias="SUITE")]
    Suite,
    #[serde(alias="test", alias="TEST")]
    Test,
}

在这种情况下,都可以接受"套房""套房"或者"套房"
而任何其他类似"套房"的情况,肯定有问题。

7

使用#[serde(rename = "name")]来改变枚举变量在序列化和反序列化时使用的字符串。

#[derive(Debug, Deserialize)]
enum ResultType {
    #[serde(rename = "suite")]
    Suite,
    #[serde(rename = "test")]
    Test,
}

#[derive(Debug, Deserialize)]
enum ResultEvent {
    #[serde(rename = "started")]
    Started,
    #[serde(rename = "failed")]
    Failed,
    #[serde(rename = "ok")]
    Ok,
}

#[derive(Debug, Deserialize)]
struct JsonResult {
    #[serde(rename(deserialize = "type"))]
    test_type: ResultType,
    event: ResultEvent,
    test_count: Option<u32>,
}


你还可以使用#[serde(alias = "name")],在反序列化时添加额外的字符串。
更多细节请查看serde文档:https://serde.rs/variant-attrs.html

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