Json in Rust

Our example demonstrates how to work with JSON in Rust, including encoding and decoding of both basic and custom data types.

use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use std::collections::HashMap;

// We'll use these two structs to demonstrate encoding and
// decoding of custom types below.
#[derive(Serialize, Deserialize)]
struct Response1 {
    page: i32,
    fruits: Vec<String>,
}

#[derive(Serialize, Deserialize)]
struct Response2 {
    page: i32,
    fruits: Vec<String>,
}

fn main() {
    // First we'll look at encoding basic data types to
    // JSON strings. Here are some examples for atomic
    // values.
    let bol_b = serde_json::to_string(&true).unwrap();
    println!("{}", bol_b);

    let int_b = serde_json::to_string(&1).unwrap();
    println!("{}", int_b);

    let flt_b = serde_json::to_string(&2.34).unwrap();
    println!("{}", flt_b);

    let str_b = serde_json::to_string(&"gopher").unwrap();
    println!("{}", str_b);

    // And here are some for slices and maps, which encode
    // to JSON arrays and objects as you'd expect.
    let slc_d = vec!["apple".to_string(), "peach".to_string(), "pear".to_string()];
    let slc_b = serde_json::to_string(&slc_d).unwrap();
    println!("{}", slc_b);

    let mut map_d = HashMap::new();
    map_d.insert("apple".to_string(), 5);
    map_d.insert("lettuce".to_string(), 7);
    let map_b = serde_json::to_string(&map_d).unwrap();
    println!("{}", map_b);

    // The serde_json crate can automatically encode your
    // custom data types.
    let res1_d = Response1 {
        page: 1,
        fruits: vec!["apple".to_string(), "peach".to_string(), "pear".to_string()],
    };
    let res1_b = serde_json::to_string(&res1_d).unwrap();
    println!("{}", res1_b);

    let res2_d = Response2 {
        page: 1,
        fruits: vec!["apple".to_string(), "peach".to_string(), "pear".to_string()],
    };
    let res2_b = serde_json::to_string(&res2_d).unwrap();
    println!("{}", res2_b);

    // Now let's look at decoding JSON data into Rust
    // values. Here's an example for a generic data
    // structure.
    let byt = r#"{"num":6.13,"strs":["a","b"]}"#;

    // We need to provide a type where serde_json can put the decoded data.
    let dat: Value = serde_json::from_str(byt).unwrap();
    println!("{:?}", dat);

    // In order to use the values in the decoded map,
    // we'll need to convert them to their appropriate type.
    let num = dat["num"].as_f64().unwrap();
    println!("{}", num);

    // Accessing nested data requires a series of
    // conversions.
    let strs = dat["strs"].as_array().unwrap();
    let str1 = strs[0].as_str().unwrap();
    println!("{}", str1);

    // We can also decode JSON into custom data types.
    let str = r#"{"page": 1, "fruits": ["apple", "peach"]}"#;
    let res: Response2 = serde_json::from_str(str).unwrap();
    println!("{:?}", res);
    println!("{}", res.fruits[0]);

    // In the examples above we always used strings as
    // intermediates between the data and JSON representation.
    // We can also stream JSON encodings directly to Writers
    // like std::io::Stdout.
    let d = json!({"apple": 5, "lettuce": 7});
    serde_json::to_writer(std::io::stdout(), &d).unwrap();
    println!();
}

To run the program, save it as json_example.rs and use cargo run.

$ cargo run
true
1
2.34
"gopher"
["apple","peach","pear"]
{"apple":5,"lettuce":7}
{"page":1,"fruits":["apple","peach","pear"]}
{"page":1,"fruits":["apple","peach","pear"]}
Object {"num": Number(6.13), "strs": Array [String("a"), String("b")]}
6.13
a
Response2 { page: 1, fruits: ["apple", "peach"] }
apple
{"apple":5,"lettuce":7}

We’ve covered the basics of JSON in Rust here, but check out the serde_json documentation for more information.