【问题标题】:Deserializing different data structures with rust serde使用 rust serde 反序列化不同的数据结构
【发布时间】:2020-04-08 03:31:01
【问题描述】:

我正在尝试反序列化从 Web API 接收到的 JSON 并且具有一些不必要的深度结构。

使用serde,是否可以像这样反序列化 JSON:

{
    "unnecessarily": {
        "deep": {
            "structure": {
                "data1": 0
            }
        }
    },
    "data2": 0
}

生锈结构:

struct Data {
   data1: usize,
   data2: usize,
}

无需手动实现Deserialize

如果不可能,还有其他合适的箱子吗?

【问题讨论】:

  • 您可以定义几个模仿 JSON 结构的结构,然后使用 from 标签自动转换为平面结构。

标签: json rust deserialization serde


【解决方案1】:

您可以使用serde's derive macro 生成SerializeDeserialize 特征的实现

use serde::Deserialize;

#[derive(Deserialize)]
struct Data {
   data1: usize,
   data2: usize,
}

如果事先不知道 JSON 结构,您可以反序列化为 serde_json::Value 并使用它

use serde_json::{Result, Value};
fn example() -> Result<()> {
    let data = r#"
        {
          "unnecessarily": {
            "deep": {
              "structure": {
                "data1": 0
              }
            }
          },
          "data2": 0
        }"#;

    let v: Value = serde_json::from_str(data)?;

    let data1 = v["unnecessarily"]["deep"]["structure"]["data1"].as_i64()?;

    Ok(())
}

【讨论】:

  • 我的问题中的JSON被简化了,实际的JSON要复杂得多,所以这种方法需要大量的代码比如let data1 = v["unnecessarily"]["deep"]["structure"]["data1"].as_i64()?;有没有更好的方法?
  • @mkihr_ojisan 好吧,我猜你必须以一种或另一种方式告诉你的代码去哪条路径去查找数据。如果你不像let data1 = v["unnecessarily"]["deep"]["structure"]["data1"].as_i64()?; 那样写它,你必须把它写在别的地方。——我读了 Russ 的建议,你通常解析,然后写一个包装器/转换器来将它转换成你更好的 Rust 数据结构。
猜你喜欢
  • 1970-01-01
  • 2020-01-14
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 2022-11-29
  • 2021-08-28
  • 1970-01-01
相关资源
最近更新 更多