Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Encoding a tree with serde_json

I’m new to Rust and have a project that requires specifying a config that is a tree. In JSON this would be like:

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

Here the root has 3 children "a,b,c" and "a" has two children "d,e" with one associated with the value 10 and another with the value 20 etc. In other words, the tree can have arbitrary depth and only leaf nodes have values associated.

My question: Is there a way to parse such a structure in Rust strait into some structs? What would be the cleanest way to parse something like this?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

What would be the cleanest way to parse something like this?

That is dependent on your use-case, I’d say. I think the simplest solution would be to parse this into an untagged enum with either a leaf with a value, or a subtree. For the subtree a HashMap can be used. Here a simple example that can parse your 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.

But like I said, it depends what you want to do with the tree in your Rust code, whether this data structure is feasible for you or not.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading