Majster Majster - 3 months ago 36
JSON Question

Rust HashMap with multiple types (for JSON serialization)

I want to make a JSON object in rust which includes multiple types. Here's the structure:

{
"key1": "value",
"key2": ["val", "val", "val"]
"key3": { "keyX": 12 }
}


So now how can I make a
HashMap
which accepts all these types in rust?

I'm trying this:

let item = HashMap::new();
item.insert("key1", someString); //type is &str
item.insert("key2", someVecOfStrings); //type is Vec<String>
item.insert("key3", someOtherHashMap); //Type is HashMap<&str, u32>

let response = json::encode(&item).unwrap();


I know that the hash map does not have enough type info. But I'm not sure how can I make it work. I have tried setting an explicit type on
item
which was
HashMap<&str, Encodable>
but then it's just another error. What is the correct way to do this?

Answer

You should use an enum type as value in your hashmap. That enum needs to have a variant for each possible type (boolean, number, string, list, map...) and an associated value of appropriate type for each variant. Actually, there is already an implementation of JSON value type here. It is part of serde_json crate. See also serde crate.

Here is how you code would look like if you use serde_json crate:

extern crate serde_json;

use serde_json::{Value, Map};

fn main() {
  let mut inner_map = Map::new();
  inner_map.insert("x".to_string(), Value::U64(10u64));
  inner_map.insert("y".to_string(), Value::U64(20u64));

  let mut map = Map::new();
  map.insert("key1".to_string(), Value::String("test".to_string()));
  map.insert("key2".to_string(), Value::Array(vec![
    Value::String("a".to_string()),
    Value::String("b".to_string())
  ]));
  map.insert("key3".to_string(), Value::Object(inner_map));

  println!("{}", serde_json::to_string(&map).unwrap());
  // => {"key1":"test","key2":["a","b"],"key3":{"x":10,"y":20}}
}