Serialization and deserialization are important concepts to understand for any kind of application needs to transfer or store data in a compact manner. Serialization is the process by which an in-memory data type can be converted into a sequence of bytes, while deserilization is the opposite of that, meaning it can read data. Many programming languages provide support for converting a data structure into a sequence of bytes. The beautiful part about serde is that it generates the serialization of any supported type at compile time, relying heavily on procedural macros. Serialization and deserialization is a zero cost operation with serde most of the time.
In this demo, we'll explore the serde crate to serialize and deserialize a user defined type. Let's create a new project by running cargo new serde_demo with the following contents in Cargo.toml:
# serde_demo/Cargo.toml
[dependencies]
serde = "1.0.84"
serde_derive = "1.0.84"
serde_json = "1.0.36"
Following are the contents in main.rs:
serde_demo/src/main.rs
use serde_derive::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize)]
struct Foo {
a: String,
b: u64
}
impl Foo {
fn new(a: &str, b: u64) -> Self {
Self {
a: a.to_string(),
b
}
}
}
fn main() {
let foo_json = serde_json::to_string(Foo::new("It's that simple", 101)).unwrap();
println!("{:?}", foo_json);
let foo_value: Foo = serde_json::from_str(foo_json).unwrap();
println!("{:?}", foo_value);
}
To serialize any native data type to a JSON-like format, we simply need to put a derive annotation over our types, which is the case of for our struct, Foo.
serde supports a lot of serializers implemented as crates. Popular examples are serde_json, bincode and TOML. More supported formats can be found at: https://github.com/TyOverby/bincode. These serialization implementors, such as the serde_json crate, provide methods such as to_string to convert