rust 使用serde_json编码树

mhd8tkvw  于 2023-03-02  发布在  其他
关注(0)|答案(1)|浏览(151)

我是Rust的新手,有一个项目需要指定一个树的配置,在JSON中可能是这样的:

{
  "a": {
    "d": {
      "val": 10
    },
    "e": {
      val: 20
    }
  },
  "b": {
    "val": 5
  },
  "c": {
    "val": 1
  }
}

这里,根具有3个子节点"a、b、c",并且"a"具有两个子节点"d、e",其中一个与值10相关联,另一个与值20相关联,等等。换句话说,树可以具有任意深度,并且只有叶节点具有相关联的值。
我的问题:有没有办法把Rust straight中的这样一个结构解析成一些structs?解析这样的东西最干净的方法是什么?

5ssjco0h

5ssjco0h1#

解析这样的东西最干净的方法是什么?
这取决于你的用例,我认为最简单的解决方案是将其解析为一个无标记的枚举,它可以是一个带值的叶子,也可以是一个子树。对于子树,可以使用HashMap。下面是一个可以解析json的简单示例:

use std::collections::HashMap;

use serde::Deserialize;

#[derive(Deserialize, PartialEq, Debug)]
#[serde(untagged)]
enum Node {
    Leaf { val: u8 },
    Tree(HashMap<String, Node>),
}

fn main() {
    let json = r#"{
      "a": {
        "d": {
          "val": 10
        },
        "e": {
          "val": 20
        }
      },
      "b": {
        "val": 5
      },
      "c": {
        "val": 1
      }
    }"#;

    let tree: Node = serde_json::from_str(json).unwrap();

    let expect = Node::Tree(HashMap::from([
        (
            "a".to_owned(),
            Node::Tree(HashMap::from([
                ("d".to_owned(), Node::Leaf { val: 10 }),
                ("e".to_owned(), Node::Leaf { val: 20 }),
            ])),
        ),
        ("b".to_owned(), Node::Leaf { val: 5 }),
        ("c".to_owned(), Node::Leaf { val: 1 }),
    ]));

    assert_eq!(tree, expect);
}

Playground.
但是就像我说的,这取决于你想在你的Rust代码中对树做什么,这种数据结构对你来说是否可行。

相关问题