Serialize and deserialize HashMap to JSON in Rust

Serialize a HashMap to JSON and deserialize JSON to a HashMap in Rust using serde_json.

  • HashMap
  • serialize
  • deserialize
  • serde_json
  • serde
  • to_string
  • from_str
  • JSON
  • assert_eq!

In most of the other articles about JSON and Rust we deal with data that can be represented by a struct where the keys are fixed and known up-front.

There are, however, cases when the keys can be arbitrary values of some type. E.g. arbitrary strings. For example if we want to count how many times a word appears in a text, the best representation might be a HashMap where we won't know up-front which words are in a text and thus won't know up-front what will be the keys.

So in this example we took a HashMap that with key-value pairs in it mapping Strings to numbers and we serialized the HashMap using serde_json::to_string to a JSON string:

#![allow(unused)]
fn main() {
let json_string = serde_json::to_string(&data_before).unwrap();
}

Then deserialized it using serde_json::from_str back to a HashMap with the appropriate type definition.

#![allow(unused)]
fn main() {
let data_after: HashMap<String, u32> = serde_json::from_str(&json_string).unwrap();
}

Actually I included two ways to deserialize, once by declaring the type of the new variable and once by using the Turbofish 🐠 operator.

#![allow(unused)]
fn main() {
let data_turbofish = serde_json::from_str::<HashMap<String, u32>>(&json_string).unwrap();
}

Use whichever makes more sense to you.

After both deserialization we used the assert_eq! macro to compare the resulting data structure to the original one.

The dependencies in Cargo.toml

We need serde_json for this.

[package]
name = "hash-to-json"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde_json = "1.0"

The code

use std::collections::HashMap;

fn main() {
    let mut data_before = HashMap::new();
    data_before.insert("foo".to_string(), 23);
    data_before.insert("bar".to_string(), 42);
    println!("{:?}", data_before);

    // serialize
    let json_string = serde_json::to_string(&data_before).unwrap();
    println!("{}", json_string);

    // deserialize
    let data_after: HashMap<String, u32> = serde_json::from_str(&json_string).unwrap();
    println!("{:?}", data_after);
    assert_eq!(data_before, data_after);

    // doing the same using Turbofish
    let data_turbofish = serde_json::from_str::<HashMap<String, u32>>(&json_string).unwrap();
    println!("{:?}", data_turbofish);
    assert_eq!(data_before, data_turbofish);

}

Running the example

cargo run

Will print:

{"bar": 42, "foo": 23}
{"bar":42,"foo":23}
{"bar": 42, "foo": 23}
{"foo": 23, "bar": 42}