【问题标题】:Deserialize numbered items using serde使用 serde 反序列化编号项目
【发布时间】:2020-03-07 00:18:37
【问题描述】:

我正在尝试使用 serde 反序列化如下所示的 JSON 数据:

{
  "item1": "Foo",
  "item2": "Bar",
  "item3": "Baz",
  "item4": null,
  "item5": null,
  "description1": "something",
  "description2": "another thing",
  "description3": "one more thing",
  "description4": null,
  "description5": null
}

可以假设只有 5 个项目,并且字段将始终存在(但可能为空)。

我希望把它放到Vec<Item> 的地方

struct Item {
    name: String,
    description: String,
}

我知道我可以#[derive(Deserialize)] 和别名字段,但我不确定如何处理将编号项目转换为列表。在 serde 中如何处理这样的案例?

【问题讨论】:

  • 如果您控制 JSON 格式,您应该将其更改为合理的格式。如果不控制格式,最简单的解决方案是定义一个与 JSON 布局相同的中间类型,并为您的目标类型实现From<Intermediary>
  • 如果你愿意,你可以在目标类型上使用#[serde(from = Intermediary)],这样serde就会为你做转换。
  • @SvenMarnach 不幸的是我无法控制它。这是有道理的。

标签: rust serde


【解决方案1】:

考虑将serde_json::from_str 解析为serde_json::Value 然后应用您的特定用例所需的转换。

#[derive(Debug)]
struct Item {
    name: String,
    description: String,
}

fn main() {
    let data = r#"
    {
        "item1": "Foo",
        "item2": "Bar",
        "item4": null,
        "item5": null,
        "description1": "something",
        "description2": "another thing",
        "description3": "one more thing",
        "description4": null,
        "description5": null
    }"#;
    let v: Value = serde_json::from_str(data).unwrap();
    let mut items = Vec::new();

    for idx in 1..6 {
        let name = format!("item{}", idx);
        let descr = format!("description{}", idx);
        if let (Value::String(value), Value::String(descr)) = (&v[name], &v[descr]) {
            items.push(Item {
                name: value.to_string(),
                description: descr.to_string(),
            })
        }
    }

    println!("items {:?}", items);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-22
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多