JoeZhao

跨出界

Hey, I’m JoeZhao, a software engineer, and a gamer.

Read and Parse JSON With Rust

Let's talk about how Rust handles JSON format/files.

My requirements are as follows:

  1. Download a JSON file from a remote address and save it locally.
  2. Read the JSON file.
  3. Search and match the content of the JSON file.
  4. Return the search results.

The main focus of this article is on step 2.
First, we need to parse the JSON format as follows:

{
    "0100000011D90000": {
        "bannerUrl": "https://img.../37fdb...f83a.jpg",
        "category": [
            "Adventure",
            "RPG"
        ],
        "description": "Welcome to the Sinnoh region! ",
        "developer": null,
        "id": "0100000011D90000",
        "isDemo": false,
        "language": "en",
        "name": "Pokémon™ Brilliant Diamond",
        "nsuId": 70010000039950,
        "numberOfPlayers": 1,
        "publisher": "Nintendo",
        "rank": 30712,
        "ratingContent": [
            "Mild Cartoon Violence",
            "Users Interact",
            "In-Game Purchases"
        ],
        "size": 7334789120,
        "version": 0
    },
    ...
}

We will mainly use the libraries serde and serde_json.

First, add the following dependencies to the Cargo.toml file:

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

Create a Data Model - Struct#

To make Rust recognize the data structure, we need to create a data model for the Game struct to mimic the JSON response.

In Rust, we use struct to describe data models. Here, we derive the Serialize/Deserialize traits from serde (allowing serialization and deserialization) and import them using the use serde::{ Deserialize, Serialize } keyword.

The code is as follows:

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Game {
    pub banner_url: Option<JsonValue>,
    pub category: Option<Vec<JsonValue>>,
    pub description: Option<JsonValue>,
    pub developer: Option<JsonValue>,
    pub id: Option<JsonValue>,
    pub is_demo: Option<JsonValue>,
    pub language: Option<JsonValue>,
    pub name: Option<JsonValue>,
    pub nsu_id: Option<usize>,
    pub number_of_players: Option<usize>,
    pub publisher: Option<JsonValue>,
    pub rank: Option<JsonValue>,
    pub rating_content: Option<Vec<JsonValue>>,
    pub size: Option<JsonValue>,
    pub version: Option<JsonValue>,
}

PS: In the Game struct, there is a slight difference in naming convention between the original JSON bannerUrl and banner_url. The former uses camel case, while the latter uses snake case. Rust prefers snake case by default.
Therefore, we need to derive #[serde(rename_all = "camelCase")], which describes the naming convention of the struct and renames all the contents in camel case.

Read the File#

Here is a simple example of reading a file:

use std::fs::File;

fn main() {
    // Read the demo.json file and output the file size
    let demo_file_path = Path::new("appdata/demo.json");
    let file = File::open(demo_file_path)?;
    // Get file metadata
    let metadata = file.metadata()?;
    println!("The File Size is: {:?} Bytes", metadata.len());
}

To read a file, use the std::fs::File module and pass the file path to the open method.

Parse the Data#

let content: HashMap<String, Game> = match serde_json::from_reader(&file) {
    Ok(content) => {
        println!("File loaded successfully");
        content
    },
    Err(e) => {
        println!("File loading error: {}", e);
        Err(e)?
    }
};

Here, we use the from_reader method from serde_json to read the file data and parse it into the format of the Game struct. If the JSON structure is incorrect, the program will exit and display the error mentioned in the Err(e) section.

By the way, if we want to read the value of a HashMap, we can use the get method, for example:

println!("{:?}", content.unwrap().get("0100000000010000").unwrap().name);

Thank you for reading.

You can find the source code of this article here: read-and-parse-json-with-rust

--EOF--

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.