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:
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.
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.
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.
examples/hash-to-json/Cargo.toml
[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
examples/hash-to-json/src/main.rs
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}