如何使用serde_json和Value枚举处理可能丢失的字段?

Jam*_*ith 1 rust serde

我有一个JSON数据流,其中某些JSON对象可能缺少某些字段或具有我事先不知道的字段。

我的解决方案是使用:

let v: Value = serde_json::from_str(data)?;
Run Code Online (Sandbox Code Playgroud)

如何处理该字段stuff?如果我知道它存在,则可以使用:

v["stuff"]
Run Code Online (Sandbox Code Playgroud)

如果数据stuff中没有字段,该如何处理?

She*_*ter 8

我的解决方案是使用 [ serde_json::Value]

我仍然会使用类型驱动的序列化,将可能丢失的字段包装在Option.

use serde::Deserialize; // 1.0.101
use serde_json; // 1.0.40

#[derive(Debug, Deserialize)]
struct Data {
    required: i32,
    missing: Option<String>,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let data = r#"{"required": 42, "extra": true}"#;
    let data = serde_json::from_str::<Data>(data)?;
    println!("{:?}", data);

    let data = r#"{"required": 42, "extra": true, "missing": "cow"}"#;
    let data = serde_json::from_str::<Data>(data)?;
    println!("{:?}", data);

    Ok(())
}
Run Code Online (Sandbox Code Playgroud)
use serde::Deserialize; // 1.0.101
use serde_json; // 1.0.40

#[derive(Debug, Deserialize)]
struct Data {
    required: i32,
    missing: Option<String>,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let data = r#"{"required": 42, "extra": true}"#;
    let data = serde_json::from_str::<Data>(data)?;
    println!("{:?}", data);

    let data = r#"{"required": 42, "extra": true, "missing": "cow"}"#;
    let data = serde_json::from_str::<Data>(data)?;
    println!("{:?}", data);

    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

如果您有在编译时无法知道名称的字段,serde_json::Value除了此解决方案外,您还可以使用。请参阅如何使用 Serde 的自定义(反)序列化来更新任意输入的子集?

也可以看看:


Pet*_*all 7

如果该字段不存在,则通过(即)的Index实现访问丢失的字段会感到恐慌。而是使用,它返回一个:Valuev["stuff"]Value::getOption

if let Some(field) = v.get("stuff") {
    println!("field = {:?}", field);
} else {
    println!("field is missing");
}
Run Code Online (Sandbox Code Playgroud)