JSON is a commonly used data object composed of key-value pairs. This article will demonstrate through multiple examples how to parse JSON content in Rust and how to convert structs into JSON strings.
Rust's serde provides JSON serialization and deserialization capabilities;
Adding Dependencies
To use the serde library for parsing JSON text, you need to add serde and serde_json dependencies to your project:
Add the following lines to your Cargo.toml file:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Parsing JSON
Parsing Untyped JSON
Any valid JSON data can be converted into the serde_json::Value type, defined as follows:
enum Value {
Null,
Bool(bool),
Number(Number),
String(String),
Array(Vec<Value>),
Object(Map<String, Value>),
}
serde_json provides several functions for parsing various forms of JSON data:
serde_json::from_str- for parsing JSON strings;serde_json::from_slice- for parsing byte slices&[u8];serde_json::from_reader- reads and parses data from objects implementing theio::Readtrait, such as files or TCP streams;
An example using serde_json::from_str:
fn main() {
// JSON data as &str
let data = r#"
{
"name": "James Bond",
"age": 33,
"pet_phrase": [
"Bond, James Bond.",
"Shaken, not stirred."
]
}"#;
// Convert to serde_json::Value
let v: serde_json::Value = serde_json::from_str(data).unwrap();
// Access data using square bracket indexing
println!("NAME: {}\nAGE: {}\n\t{}\n\t{}",
v["name"],
v["age"],
v["pet_phrase"][0],
v["pet_phrase"][1],
);
}
Program Output
NAME: "James Bond"
AGE: 33
"Bond, James Bond."
"Shaken, not stirred."
Parsing JSON into Custom Data Structures
serde provides Serialize and Deserialize traits to define serialization and deserialization behavior for data structures.
Modifying the previous example to use custom data structures with Serialize and Deserialize:
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct Person {
name: String,
age: u8,
pet_phrase: Vec<String>,
}
fn main() {
// JSON data as &str
let data = r#"
{
"name": "James Bond",
"age": 33,
"pet_phrase": [
"Bond, James Bond.",
"Shaken, not stirred."
]
}"#;
// Convert to Person struct
let p: Person = serde_json::from_str(data).unwrap();
// Access struct fields directly
println!("NAME: {}\nAGE: {}\n\t{}\n\t{}",
p.name,
p.age,
p.pet_phrase[0],
p.pet_phrase[1],
);
}
This code produces the same output as the previous example, but this time we assigned the return value of serde_json::from_str to a custom Person type.
Errors will occur if the JSON data doesn't match the struct definition;
Converting Data Structures to JSON Strings
serde provides functions to convert data structures into JSON:
serde_json::to_string- converts data structures to JSON strings;serde_json::to_vec- serializes data structures toVec<u8>;serde_json::to_writer- serializes to any object implementing theio::Writetrait, such as files or TCP streams;
An example using serde_json::to_string:
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct Person {
name: String,
age: u8,
pet_phrase: Vec<String>,
}
fn main() {
let mut pp = Vec::new();
pp.push("hello world".to_string());
pp.push("perfcode.com".to_string());
let p = Person {
name: "ho".to_string(),
age: 18,
pet_phrase: pp,
};
// Serialize to JSON string
let s = serde_json::to_string(&p).unwrap();
println!("{}",s);
}
Program Output
{"name":"ho","age":18,"pet_phrase":["hello world","perfcode.com"]}
The json! Macro
serde provides a json! macro for naturally constructing serde_json::Value objects:
The .to_string() method can convert serde_json::Value objects into JSON strings:
use serde_json::json;
fn main() {
let info = json!(
{
"name": "James Bond",
"age": 33,
"pet_phrase":[
"Bond, James Bond.",
"Shaken, not stirred."
]
}
);
// Access data using square bracket indexing
println!("NAME: {}\nAGE: {}\n\t{}\n\t{}",
info["name"],
info["age"],
info["pet_phrase"][0],
info["pet_phrase"][1],
);
// Serialize
println!("{}",info.to_string());
}
Program Output
NAME: "James Bond"
AGE: 33
"Bond, James Bond."
"Shaken, not stirred."
{"age":33,"name":"James Bond","pet_phrase":["Bond, James Bond.","Shaken, not stirred."]}