Better way to turn a String to HashMap

I have the following str:

let my_str = "{
    name: Bob,
    age: 10,
    infomation: {
        addr: nothing,
        phone: 1,
    },
}";

I'm trying to turn it to a HashMap<String, String>, the result may look like this:

let mut res = HashMap::new();
res.insert("name", "Bob");
res.insert("age", "10");
res.insert("information", "{
    addr: nothing,
    phone: 1,
}")

To get that, I could write function to analysis the str, but I could imagine that would be complicated to some extend. So is there other better way to do that?

It sounds like you are trying to deserialize something that looks almost like JSON or Rust's Debug output. Normally, I would recommend looking into serde, but there isn't anything that would be able to deserialize your data out of the box.

Can you tell us more about what you are trying to achieve? There may be an easier way to do things if we tweak the problem a little bit.

2 Likes

I am trying to build a local website, which can accept some input text, which is not pure Rust but more less verbose. And then I convert the input text to a String of pure Rust kind, and the String will be passed to irust_repl (which is a Rust crate of evaluating String) and run the converted code.
For example:
I input the following text in the website:

And then, if I can convert the input text into a HashMap<String, String>, then I can do this:

//let hm = already got HashMap;

let converted_string = format!(
    "
    #[derive(Clone, Serialize, Deserialize)]
    struct {};


    #[typetag::serde]
    impl Ta for {} {
        fn calc_di<'a>(&self, di: &'a Di) -> Vec<&'a Vec<f32>> {}

        fn calc_da(&self, da: Vec<&[f32]>) -> Vec<Vec<f32>> {}
    }
    ",
    hm["name"], hm["name"], hm["calc_di"], hm["calc_da"]
)

And the converted_string is actually this:

#[derive(Clone, Serialize, Deserialize)]
struct TwoMa(n, m);


#[typetag::serde]
impl Ta for TwoMa {
    fn calc_di<'a>(&self, di: &'a Di) -> Vec<&'a Vec<f32>> {
        vec![di.c()]
    }

    fn calc_da(&self, da: Vec<&[f32]>) -> Vec<Vec<f32>> {
        let data1 = data[0].roll(RollFunc::Mean, RollOps::N(self.0));
        let data2 = data[0].roll(RollFunc::Mean, RollOps::N(self.1));
        vec![data1, data]
    }
}

And finally the converted_string can be evaluate by irust_repl.

It sounds like you are effectively trying to build your own programming language, and not just trying to deserialize some data.

If that's the case, I would highly suggest following the formal route of creating a lexer and parser for your programming language that parses source code into some abstract tree which represents the user's program, and from there you can traverse the tree and turn it into Rust source code (or maybe you don't need to generate & compile Rust source code at all and can just turn the tree into data that can be consumed by a program).

It's much more verbose than a simple #[derive(Deserialize)], but the code is going to be a lot more reliable and well structured than trying to bodge something together.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.