Serialization: The process of converting data structures or objects into binary sequences.

Deserialization: The process of converting binary sequences generated during serialization into data structures or objects.

Serde is a common framework for serializing and deserializing Rust data structures.

In the Serde trait

Serde defines four traits:

  • Deserialize A data structure that can be deserialized from any data format supported by Serde.
  • Deserializer A data format that can deserialize any data structure supported by Serde.
  • Serialize A data structure that can be serialized into any data format supported by Serde.
  • Serializer A data format that can serialize any data structure supported by Serde.

SerializeDeserialize

Definitions of Serialize and Deserialize:

pub trait Serialize {
    pub fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer;
}
pub trait Deserialize<'de> :Sized {
    pub fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>;
}
Copy the code

For a data type to support serialization and deserialization, the type needs to implement Serialize and Deserialize traits. Serde provides Serialize and Deserialize implementations of Rust base types and standard library types.

For custom types, we can implement the Serialize and Deserialize traits ourselves. In addition, Serde provides a macro serde_derive that automatically generates Serialize and Deserialize implementations for structure types and enumeration types. This feature requires a Rust compiler version 1.31 or later, and you need to specify it using Features when configuring Serde dependencies in the Cargo. Such as:

[dependencies]
serde = { version = "1.0", features = ["derive"]}Copy the code

It can then be imported and used in code, for example:

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct Point {
    x: i32,
    y: i32,}Copy the code

SerializerDeserializer

The Serializer and Deserializer are provided by Crate, for example, serde_JSON, serde_YAMl, and bincode.

Some of the data formats implemented by the community:

  • JSON, the ubiquitous JavaScript Object Notation used – by many HTTP APIs.
  • Bincode, a compact binary format used for IPC within – the Servo rendering engine.
  • CBOR, a Concise Binary Object Representation designed – for small message size without the need for version – negotiation.
  • YAML, a self-proclaimed human-friendly configuration – language that ain’t markup language.
  • MessagePack, an efficient binary format that resembles – a compact JSON.
  • TOML, a minimal configuration format used by Cargo.
  • Pickle, a format common in the Python world.
  • RON, a Rusty Object Notation.
  • BSON, the data storage and network transfer format – used by MongoDB.
  • Avro, a binary format used within Apache Hadoop, with – support for schema definition.
  • JSON5, A superset of JSON including some productions – from ES5.
  • Postcard, a no_std and embedded-systems friendly – compact binary format.
  • URL query strings, in the x-www-form-urlencoded format.
  • Envy, a way to deserialize environment variables into – Rust structs. (deserialization only)
  • Envy Store, a way to deserialize AWS Parameter Store – parameters into Rust structs. (deserialization only)
  • S-expressions, the textual representation of code and – data used by the Lisp language family.
  • D-Bus’s binary wire format.
  • FlexBuffers, the schemaless cousin of Google’s – FlatBuffers zero-copy serialization format.
  • DynamoDB Items, the format used by rusoto_dynamodb to – transfer data to and from DynamoDB.

Serde JSON

Add dependencies to the Cargo. Toml file:

[dependencies]
serde_json = "1.0"
Copy the code

serialization

Serde_json Crate provides three functions to convert Rust data types to JSON: serde_json::to_string, serde_json::to_vec, and serde_json::to_writer String, Vec< U8 >, and IO ::Write (such as files or TCP streams).

Example:

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.
    letj = serde_json::to_string(&address)? ;// Print, write to a file, or send to an HTTP server.
    println!("{}", j);

    Ok(())}Copy the code

deserialization

Serde_json Crate provides serde_json::from_str, serde_JSON ::from_slice, and serde_json::from_reader for slicing strings, bytes (&[u8]), and IO The input (file or TCP stream) is resolved to the corresponding Rust data type.

Example:

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.
    letp: 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(())}Copy the code

If a JSON-formatted data has no corresponding Rust data type, it can be parsed as serde_JSON ::Value. This is a recursive enumerated type provided by Serde_JSON Crate that can represent any valid JSON data and is defined as follows:

enum Value {
    Null,
    Bool(bool),
    Number(Number),
    String(String),
    Array(Vec<Value>),
    Object(Map<String, Value>),
}
Copy the code

Parse JSON data into serde_json::Value using the serde_json::from_str, serde_JSON ::from_slice, and serde_json::from_reader functions. The return values of these three functions are generic, and the return value type is determined by the type assigned to the variable.

Example:

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.
    letv: Value = serde_json::from_str(data)? ;// let v = serde_json::from_str::
      
       (data)? ; // Or you can write it like this
      

    // Access parts of the data by indexing with square brackets.
    println!("Please call {} at the number {}", v["name"], v["phones"] [0]);

    Ok(())}Copy the code

RON

Add dependencies to the Cargo. Toml file:

[dependencies]
ron = "0.6.4"
Copy the code

RON(Rusty Object Notation) is a serialization format similar to Rust syntax that supports all Serde data models.

RON example:

Scene( // class name is optional
    materials: { // this is a map
        "metal": (
            reflectivity: 1.0,),"plastic": (
            reflectivity: 0.5,
        ),
    },
    entities: [ // this is an array
        (
            name: "hero",
            material: "metal",
        ),
        (
            name: "monster",
            material: "plastic",),,)Copy the code

RON format features:

  • use(..)Represents a structure, used{.. }Indicates Map[...]Represents an array. You cannot distinguish between a structure and a Map when using JSON.
  • You can add comments; you can’t add comments in JSON.
  • As with Rust syntax, the last item is comma.

ron::value::Value

Like Serde_JSON Crate, RON Crate uses recursive enumerated types to represent RON formatted data. The enumeration type is: RON ::value:: value, which is defined as follows:

pub enum Value {
    Bool(bool),
    Char(char),
    Map(Map),
    Number(Number),
    Option(Option<Box<Value>>),
    String(String),
    Seq(Vec<Value>),
    Unit,
}
Copy the code

Serialization and deserialization

Serialization functions provided by RON Crate:

  • ron::ser::to_string: Serializes value and returns it as string.
  • ron::ser::to_string_pretty: Serializes value in the recommended RON layout in a pretty way.
  • ron::ser::to_writer: Serializes value into writer.
  • ron::ser::to_writer_pretty: Serializes value into writer in a pretty way.

Deserialization functions provided by RON Crate:

  • ron::de::from_bytes: Building a deserializer and deserializing a value of type T from bytes.
  • ron::de::from_str: Reading data from a reader and feeding into a deserializer.
  • ron::de::from_reader: Building a deserializer and deserializing a value of type T from a string.

Example:

use serde::{Deserialize, Serialize};
use std::fs::File;

#[derive(Serialize, Deserialize, Debug)]
struct Point {
    x: i32,
    y: i32,}fn main() {
    let point1 = Point { x: 1, y: 2 };
    // Serializes point1 into a buffer
    let mut buf = Vec: : <u8>::new();
    ron::ser::to_writer(&mut buf, &point1).unwrap();
    println!("buf = {:? }", buf);

    let point2: Point = ron::de::from_bytes(&buf).unwrap();
    println!("point2: {:? }", point2);

    let point3 = Point { x: 3, y: 4 };
    // Serializes point3 and returns it as string
    let point_str = ron::to_string(&point3).unwrap();
    println!("point_str: {:? }", point_str);

    let point4: Point = ron::from_str(&point_str).unwrap();
    println!("point4: {:? }", point4);

    let point5 = Point { x: 5, y: 6 };
    let file = File::create("foo.txt").unwrap();
    // Serializes point5 into foo.txt
    ron::ser::to_writer(file, &point5).unwrap();

    let file = File::open("foo.txt").unwrap();
    let point6: Point = ron::de::from_reader(file).unwrap();
    println!("point6: {:? }", point6);
}
Copy the code

BSON

Add dependencies to the Cargo. Toml file:

[dependencies]
bson = "1.1.0"
Copy the code

BSON(Binary JSON) is a JSON-like format (document) in Binary form.

BSON example:

// JSON equivalent
{"hello": "world"}

// BSON encoding
\x16\x00\x00\x00                   // total document size
\x02                               // 0x02 = type String
hello\x00                          // field name
\x06\x00\x00\x00world\x00          // field value
\x00                               // 0x00 = type EOO ('end of object')
Copy the code

BSON value

Many different data types can be represented as BSON values, and the BSON enumerated types define all types that can be represented as BSON values.

Example: Create a Bson instance

// Create the Bson instance directly
let string = Bson::String("hello world".to_string());
let int = Bson::Int32(5);
let array = Bson::Array(vec![Bson::Int32(5), Bson::Boolean(false)]);

// Use into() to create a Bson instance
let string: Bson = "hello world".into();
let int: Bson = 5i32.into();

/ / use ` bson! 'macro creates Bson instance
letstring = bson! ("hello world");
letint = bson! (5);
letarray = bson! ([5.false]);
Copy the code

BSON documents

Documents in Bson consist of an ordered set of key-value pairs, similar to objects in JSON. It also contains the size of the space taken up by the Bson value.

Example 1: Create a document instance

let mut bytes = hex::decode("0C0000001069000100000000").unwrap();
// Create it directly
let doc = Document::from_reader(&mut bytes.as_slice()).unwrap(); // { "i": 1 }

/ / by doc! create
let doc = doc! {
   "hello": "world"."int": 5."subdoc": { "cat": true}};Copy the code

Example 2: Accessing document members

let doc = doc! {
   "string": "string"."bool": true."i32": 5."doc": { "x": true}};// attempt get values as untyped Bson
let none = doc.get("asdfadsf"); // None
let value = doc.get("string"); // Some(&Bson::String("string"))

// attempt to get values with explicit typing
let string = doc.get_str("string"); // Ok("string")
let subdoc = doc.get_document("doc"); // Some(Document({ "x": true }))
let error = doc.get_i64("i32"); // Err(...)
Copy the code

Serialization and deserialization

Bson Crate provides the serialization function:

  • bson::to_bson: Encode a T Serializable into a BSON Value.
  • bson::to_document: Encode a T Serializable into a BSON Document.

Bson Crate provides the deserialization function:

  • bson::from_bson: Decode a BSON Value into a T Deserializable.
  • bson::from_document: Decode a BSON Document into a T Deserializable.

Example:

use bson::*;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: i32,
    phones: Vec<String>,}fn main() {
    // Some BSON input data as a `Bson`.
    letbson_data: Bson = bson! ({"name": "John Doe"."age": 43."phones": [
            "+ 44 1234567"."+ 44 2345678"]});// Deserialize the Person struct from the BSON data.
    let person: Person = bson::from_bson(bson_data).unwrap();

    // Do things just like with any other Rust data structure.
    println!("Redacting {}'s record.", person.name);

    // Get a serialized version of the input data as a `Bson`.
    let redacted_bson = bson::to_bson(&person).unwrap();
    println!("{}", redacted_bson);
}
Copy the code

The relevant data

Serde

JSON

RON

BSON