rust 将json初始化为enum [duplicate]

0pizxfdo  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(124)

此问题在此处已有答案

How can I support an unknown or other value for a Serde enum?(5个答案)
上个月关门了。
我正在尝试对json进行编译,但无法得到预期的结果。下面是我的代码:

use serde::{Serialize, Deserialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
struct StudentData{
    stu1: TestResult,
    stu2: TestResult,
    stu3: TestResult,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
enum TestResult{
    #[serde(rename = "fail")]
    Fail,
    #[serde(rename = "absent")]
    Absent,
    Pass(String)
}

fn main() {
    let json_string = "{\"stu1\":\"50\",\"stu2\":\"fail\",\"stu3\":\"absent\"}";
    let s: StudentData = serde_json::from_str(json_string).expect("should provide student data");
    println!("{:#?}", s);
}

字符串
输出

StudentData {
    stu1: Pass(
        "50",
    ),
    stu2: Pass(
        "fail",
    ),
    stu3: Pass(
        "absent",
    ),
}


我想得到的是:

StudentData {
    stu1: Pass(
        "50",
    ),
    stu2: Fail,
    stu3: Absent,
}


这可行吗?

5uzkadbs

5uzkadbs1#

这种行为让我有点惊讶,显然,如果你在一个未标记的枚举中有单元变量,它们会被序列化为null JSON值。

println!("{}", serde_json::to_string(&TestResult::Fail).unwrap());

字符串
指纹

null


我假设serde同样需要一个null,你可以通过不把整个enum做成untagged,而只做成Pass的变体来解决这个问题。

#[derive(Debug, Clone, Serialize, Deserialize)]
enum TestResult {
    #[serde(rename = "fail")]
    Fail,
    #[serde(rename = "absent")]
    Absent,
    #[serde(untagged)]
    Pass(String),
}


(顺便说一句,我不太喜欢你的表示法。为什么点数是一个字符串,而不是一个数字?它应该有自己的标签,比如"pass": {"score": 50}。(如果你有半个点,舍入可能是一个问题。(rel:arbitrary_precision))

相关问题