This is a tutorial on how to use Serde JSON to serialize and deserialize data.
Introduction
Serde JSON is framework for serializing and deserializing Rust data structures efficiently and generically.
How to Install it
In your Cargo.toml
declare serde_json as a dependency:
[dependencies]
serde_json = "1.0"
Data Representations
Serde provides ways to convert between the following representations of JSON data:
- Text data
- Untyped or Loosely typed representation
- Strongly typed data
Simple Examples
Example 1 - Work on Untyped JSON values
A string of JSON data can be parsed into a serde_json::Value by the serde_json::from_str function. There is also from_slice for parsing from a byte slice &[u8] and from_reader for parsing from any io::Read like a File or a TCP stream.
use serde_json::{Result, Value};
fn untyped_example() -> Result<()> {
// Some JSON input data as a &str. Maybe this comes from the user.
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
// Parse the string of data into serde_json::Value.
let v: Value = serde_json::from_str(data)?;
// Access parts of the data by indexing with square brackets.
println!("Please call {} at the number {}", v["name"], v["phones"][0]);
Ok(())
}
fn main() {
untyped_example().unwrap();
}
If you run it you will get;
Please call "John Doe" at the number "+44 1234567"
Example 2: Parsing JSON as strongly typed data structures
Serde provides a powerful way of mapping JSON data into Rust data structures largely automatically.
use serde::{Deserialize, Serialize};
use serde_json::Result;
#[derive(Serialize, Deserialize)]
struct Person {
name: String,
age: u8,
phones: Vec<String>,
}
fn typed_example() -> Result<()> {
// Some JSON input data as a &str. Maybe this comes from the user.
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
// Parse the string of data into a Person object. This is exactly the
// same function as the one that produced serde_json::Value above, but
// now we are asking it for a Person as output.
let p: Person = serde_json::from_str(data)?;
// Do things just like with any other Rust data structure.
println!("Please call {} at the number {}", p.name, p.phones[0]);
Ok(())
}
If you run you get:
Please call John Doe at the number +44 1234567
Example 3: Constructing JSON values
Serde JSON provides a json! macro to build serde_json::Value objects with very natural JSON syntax.
use serde_json::json;
fn main() {
// The type of john
is serde_json::Value
let john = json!({
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
});
println!("first phone number: {}", john["phones"][0]);
// Convert to a string of JSON and print it out
println!("{}", john.to_string());
}
If you run you willget:
first phone number: "+44 1234567"
{"age":43,"name":"John Doe","phones":["+44 1234567","+44 2345678"]}
Example 4: Create JSON By serializing Data Structure
Using the serde_json::to_string
you can convert a data structure to JSON string.
You can also use serde_json::to_vec
to serialize to a Vec<u8>
and serde_json::to_writer
to serialize to any io::Write
such as a File or a TCP stream.
use serde::{Deserialize, Serialize};
use serde_json::Result;
#[derive(Serialize, Deserialize)]
struct Address {
street: String,
city: String,
}
fn print_an_address() -> Result<()> {
// Some data structure.
let address = Address {
street: "10 Downing Street".to_owned(),
city: "London".to_owned(),
};
// Serialize it to a JSON string.
let j = serde_json::to_string(&address)?;
// Print, write to a file, or send to an HTTP server.
println!("{}", j);
Ok(())
}
fn main() {
print_an_address().unwrap();
}
If you run you will get:
{"street":"10 Downing Street","city":"London"}
Reference
Read more here
Serde JSON RPC Example
Step 1: Install
Declare your dependencies in your Cargo.toml
as follows:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Step 2: Write Code
here is the full code:
use serde::{Serialize, Deserialize};
use serde::{Serializer, Deserializer};
use serde_json::Value;
use serde_json::json;
use serde::de::Error;
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "method", content = "params")]
#[serde(rename_all = "snake_case")]
enum MyRequests {
ItemAtIndex { index: usize },
Length,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "method", content = "params")]
#[serde(rename_all = "snake_case")]
enum MyNotifications {
InsertItem { item: Value, index: usize },
ShrinkToFit { }
}
#[derive(Debug)]
enum JsonRpc<N, R> {
Request(usize, R),
Notification(N),
}
impl<N, R> Serialize for JsonRpc<N, R>
where N: Serialize,
R: Serialize
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
match *self {
JsonRpc::Request(id, ref r) => {
let mut v = serde_json::to_value(r).map_err(serde::ser::Error::custom)?;
v["id"] = json!(id);
v.serialize(serializer)
}
JsonRpc::Notification(ref n) => n.serialize(serializer),
}
}
}
impl<'de, N, R> Deserialize<'de> for JsonRpc<N, R>
where N: Deserialize<'de>,
R: Deserialize<'de>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
#[derive(Deserialize)]
struct IdHelper {
id: Option<usize>,
}
let v = Value::deserialize(deserializer)?;
let helper = IdHelper::deserialize(&v).map_err(Error::custom)?;
match helper.id {
Some(id) => {
let r = R::deserialize(v).map_err(Error::custom)?;
Ok(JsonRpc::Request(id, r))
}
None => {
let n = N::deserialize(v).map_err(Error::custom)?;
Ok(JsonRpc::Notification(n))
}
}
}
}
fn main() {
let j = r#"{
"id": 42,
"method": "item_at_index",
"params": {
"index": 5
}
}"#;
let k = r#"{
"method": "insert_item",
"params": {
"index": 5,
"item": 42
}
}"#;
let l = r#"{
"method": "shrink_to_fit",
"params": {}
}"#;
type T = JsonRpc<MyNotifications, MyRequests>;
println!("{:?}", serde_json::from_str::<T>(j).unwrap());
println!("{:?}", serde_json::from_str::<T>(k).unwrap());
println!("{:?}", serde_json::from_str::<T>(l).unwrap());
}
Step 3: Run
Run the code above and you will get:
Request(42, ItemAtIndex { index: 5 })
Notification(InsertItem { item: Number(42), index: 5 })
Notification(ShrinkToFit)
Reference
Find the download link below:
Number | Link |
---|---|
1. | Download example |
2. | Follow code author |