Сериализация: процесс преобразования структуры данных или объекта в двоичную последовательность.
десериализовать: процесс преобразования двоичной последовательности, сгенерированной во время сериализации, в структуру данных или объект.
Serde — это общая структура для сериализации и десериализации структур данных Rust.
Черты Серде
Серде определяет 4 черты:
- 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.
Serialize
а такжеDeserialize
Serialize
а также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>;
}
Чтобы тип данных поддерживал сериализацию и десериализацию, тип должен реализоватьSerialize
а такжеDeserialize
черта. Serde предоставляет примитивы Rust и стандартные типы библиотек.Serialize
а такжеDeserialize
выполнить.
Для пользовательских типов мы можем реализовать это самиSerialize
а такжеDeserialize
черта. Кроме того, Serde предоставляет макросserde_derive
автоматически генерировать для типов структур и типов перечисленияSerialize
а такжеDeserialize
выполнить. Эта функция требует, чтобы версия компилятора Rust была1.31
и выше, и вCargo.toml
При настройке зависимостей Serde в файле необходимо использоватьfeatures
Укажите это свойство. Например:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
Затем его можно импортировать и использовать в коде, например:
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
Serializer
а такжеDeserializer
Serializer
а такжеDeserializer
Реализации предоставляются сторонними крейтами, такими как:serde_json, serde_yamlа такжеbincode.
Частичный формат данных для реализации сообщества:
- 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
существуетCargo.toml
Добавьте зависимости в файл:
[dependencies]
serde_json = "1.0"
Сериализация
serde_json Crate предоставляетserde_json::to_string
,serde_json::to_vec
а такжеserde_json::to_writer
Три функции для преобразования типов данных Rust в JSONString
,Vec<u8>
а такжеio::Write
(например, файл или поток TCP).
Пример:
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(())
}
десериализовать
serde_json Crate предоставляетserde_json::from_str
,serde_json::from_slice
а такжеserde_json::from_reader
Три функции нарезают строки, байты (&[u8]
) и ввода-вывода (файл или поток TCP) в соответствующий тип данных Rust.
Пример:
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(())
}
Если данные формата JSON не имеют соответствующего типа данных Rust, их можно проанализировать какserde_json::Value
Типы.这是 serde_json Crate 提供的一个递归的枚举类型,它可以表示任何有效的 JSON 数据,其定义如下:
enum Value {
Null,
Bool(bool),
Number(Number),
String(String),
Array(Vec<Value>),
Object(Map<String, Value>),
}
Разобрать данные формата JSON какserde_json::Value
тип, также используется:serde_json::from_str
,serde_json::from_slice
а такжеserde_json::from_reader
три функции. Возвращаемое значение этих трех функций является универсальным, а тип возвращаемого значения определяется типом, присвоенным переменной.
Пример:
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)?;
// let v = serde_json::from_str::<Value>(data)?; // 或者可以这样写
// Access parts of the data by indexing with square brackets.
println!("Please call {} at the number {}", v["name"], v["phones"][0]);
Ok(())
}
RON
существуетCargo.toml
Добавьте зависимости в файл:
[dependencies]
ron = "0.6.4"
RON (Rusty Object Notation) — это формат сериализации, аналогичный синтаксису Rust, который поддерживает всеМодель данных Серде.
Пример РОН:
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",
),
],
)
Особенности формата РОН:
- использовать
(..)
Для представления структуры используйте{..}
Чтобы представить карту, используйте[..]
представляет собой массив. При работе с JSON нет различий между структурами и картами. - Комментарии можно добавлять, но не в формате JSON.
- Как и в синтаксисе Rust, запятые добавляются к последнему элементу.
ron::value::Value
Подобно ящику serde_json, ящик ron также использует типы рекурсивного перечисления для представления данных формата RON. Этот тип перечисления:ron::value::Value
, который определяется следующим образом:
pub enum Value {
Bool(bool),
Char(char),
Map(Map),
Number(Number),
Option(Option<Box<Value>>),
String(String),
Seq(Vec<Value>),
Unit,
}
Сериализация и десериализация
Функции сериализации, предоставленные Роном Крейтом:
-
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.
Функции десериализации, предоставленные Роном Крейтом:
-
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.
Пример:
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);
}
BSON
существуетCargo.toml
Добавьте зависимости в файл:
[dependencies]
bson = "1.1.0"
BSON (Binary JSON) — это JSON-подобный формат (документ) в двоичной форме.
пример BSON:
// 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')
Значение BSON
Многие различные типы данных могут быть представлены как значения BSON,BsonТипы перечисления определяют все типы, которые могут быть представлены как значения BSON.
Пример: создать экземпляр Bson
// 直接创建 Bson 实例
let string = Bson::String("hello world".to_string());
let int = Bson::Int32(5);
let array = Bson::Array(vec![Bson::Int32(5), Bson::Boolean(false)]);
// 使用 into() 创建 Bson 实例
let string: Bson = "hello world".into();
let int: Bson = 5i32.into();
// 使用 `bson!` 宏创建 Bson 实例
let string = bson!("hello world");
let int = bson!(5);
let array = bson!([5, false]);
BSON documents
Документ в Bson состоит из упорядоченного набора пар ключ-значение, подобно Object в JSON. Кроме того, также включен размер пространства, занимаемого значением Bson.
Пример 1: создать экземпляр документа
let mut bytes = hex::decode("0C0000001069000100000000").unwrap();
// 直接创建
let doc = Document::from_reader(&mut bytes.as_slice()).unwrap(); // { "i": 1 }
// 通过 doc! 创建
let doc = doc! {
"hello": "world",
"int": 5,
"subdoc": { "cat": true },
};
Пример 2: доступ к членам документа
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(...)
Сериализация и десериализация
Функции сериализации, предоставляемые bson Crate:
-
bson::to_bson
: Encode a T Serializable into a BSON Value. -
bson::to_document
: Encode a T Serializable into a BSON Document.
Функции десериализации, предоставляемые bson Crate:
-
bson::from_bson
: Decode a BSON Value into a T Deserializable. -
bson::from_document
: Decode a BSON Document into a T Deserializable.
Пример:
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`.
let bson_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);
}