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::Read
trait, 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::Write
trait, 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."]}