Serialize 特征看起来像这样:
pub trait Serialize {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer;
}这个方法的功能是传入你的类型 (&self) 并通过调用给定的 Serializer 其中的一个方法将其映射到 Serde 数据模型。
在大多数场景中,Serde 的派生都可以为你的 crate 中的结构体或枚举生成合适的Serialize实现。当此派生不支持某个类型时,你需要为其自定义序列化行为,你可以自己实现Serialize。
作为一个最简单的例子,这里有一个i32原始类型的内置Serialize实现。
impl Serialize for i32 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_i32(*self)
}
}Serde 为 Rust 的所有原始类型都提供了这样的实现,因此你不需要再为它们手动实现了,但是如果你有一个类型需要以其序列化的形式表示为原始类型,serialize_i32和其他类似的方法将会很有用。举个例子,你可以将一个类 C 的枚举序列化成一个原始数字。
复合类型遵循初始化,元素,结束三个步骤。
use serde::ser::{Serialize, Serializer, SerializeSeq, SerializeMap};
impl<T> Serialize for Vec<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(self.len()))?;
for e in self {
seq.serialize_element(e)?;
}
seq.end()
}
}
impl<K, V> Serialize for MyMap<K, V>
where
K: Serialize,
V: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = serializer.serialize_map(Some(self.len()))?;
for (k, v) in self {
map.serialize_entry(k, v)?;
}
map.end()
}
}serialize_tuple方法与serialize_seq非常像。唯一的区别就是serialize_tuple不需要对元组的长度进行序列化,因为它可以在反序列化期间获得。常见的例子是 Rust 中的元组以及数组。在非自描述格式中,需要对Vec<T>的长度进行序列化,以便能够对Vec<T>进行反序列化。但是一个[T; 16]可以使用serialize_tuple进行序列化,因为长度在反序列化时已知,无需查看序列化的字节。
Serde 区分四种类型的结构体。普通结构体和元组结构体像序列或 map 一样遵循初始化,元素,结束的三个序列化步骤。newtype 结构体和单元结构体更像原始类型。
// An ordinary struct. Use three-step process:
// 1. serialize_struct
// 2. serialize_field
// 3. end
struct Color {
r: u8,
g: u8,
b: u8,
}
// A tuple struct. Use three-step process:
// 1. serialize_tuple_struct
// 2. serialize_field
// 3. end
struct Point2D(f64, f64);
// A newtype struct. Use serialize_newtype_struct.
struct Inches(u64);
// A unit struct. Use serialize_unit_struct.
struct Instance;结构体和 map 在某些形式上可能看起来很相似,包括 JSON。区别是 Serde 在编译期间有一个常量字符串作为 key以便在反序列化时不需要再去查找序列化的数据。这种条件使某些数据格式可以比映射更有效,更紧凑的处理结构。
数据结构将 newtype 结构视为其内部值的不重要的封装器,仅对其内部之进行序列化。请查看示例:JSON 处理 newtype 结构
use serde::ser::{Serialize, Serializer, SerializeStruct};
struct Color {
r: u8,
g: u8,
b: u8,
}
impl Serialize for Color {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// 3 is the number of fields in the struct.
let mut state = serializer.serialize_struct("Color", 3)?;
state.serialize_field("r", &self.r)?;
state.serialize_field("g", &self.g)?;
state.serialize_field("b", &self.b)?;
state.end()
}
}序列化枚举变体与序列化结构体很相似。
enum E {
// Use three-step process:
// 1. serialize_struct_variant
// 2. serialize_field
// 3. end
Color { r: u8, g: u8, b: u8 },
// Use three-step process:
// 1. serialize_tuple_variant
// 2. serialize_field
// 3. end
Point2D(f64, f64),
// Use serialize_newtype_variant.
Inches(u64),
// Use serialize_unit_variant.
Instance,
}Serializer特征还包含另外两种特殊情况。
serialize_bytes用来序列化&[u8]。一些格式将字节当作另一种序列,但是一些结构可以将字节序列化的更紧凑。目前在Serialize的实现中并没有将serialize_bytes用于&[u8]或者Vec<u8>的序列化,但是一旦该规范应用于稳定的 Rust 时就会开始使用它。目前 serde_bytes 库中的serialize_bytes可用于有效的处理&[u8]和Vec<u8>。
最后,serialize_some和serialize_none对应于Option::Some和Option::None。与其他枚举相比,用户对Option枚举的期望往往不同。Serde JSON 将会将Option::None序列化为null,将Option::Some序列化为其具体包含的值。