Serialize
trait 如下所示:
use serde::Serializer;
pub trait Serialize {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer;
}
fn main() {}
这个方法的作用是取出你的类型 (&self
),通过在给定的 Serializer
上调用恰当的一个方法来映射它到 Serde 数据模型。
在大多数情况下,Serde的派生能够为你的 crate 中定义的结构体和枚举生成适当的 Serialize
实现。如果你需要自定义某种类型的序列化行为,而派生不支持,你可以自己实现 Serialize
。
作为最简单的示例,这里是内置的 i32
的 Serialize
实现。
use std::os::raw::c_int as ActualI32;
use serde::{Serialize, Serializer};
#[allow(dead_code, non_camel_case_types)]
struct i32;
trait Serialize2 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer;
}
impl Serialize for i32 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
impl Serialize2 for ActualI32 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_i32(*self)
}
}
_ = serializer;
unimplemented!()
}
}
fn main() {}
Serde 为所有 Rust 的 基本类型 提供了这样的实现,因此你无需自己实现它们,但是 serialize_i32
和类似方法可能在你的类型需要以原始形式表示时很有用。例如,你可以 将类似 C 的 enum 序列化为基本类型的数字。
复合类型遵循初始化(init),元素(elements),结束(end)的三步过程。
use std::marker::PhantomData;
struct Vec<T>(PhantomData<T>);
impl<T> Vec<T> {
fn len(&self) -> usize {
unimplemented!()
}
}
impl<'a, T> IntoIterator for &'a Vec<T> {
type Item = &'a T;
type IntoIter = Box<dyn Iterator<Item = &'a T>>;
fn into_iter(self) -> Self::IntoIter {
unimplemented!()
}
}
struct MyMap<K, V>(PhantomData<K>, PhantomData<V>);
impl<K, V> MyMap<K, V> {
fn len(&self) -> usize {
unimplemented!()
}
}
impl<'a, K, V> IntoIterator for &'a MyMap<K, V> {
type Item = (&'a K, &'a V);
type IntoIter = Box<dyn Iterator<Item = (&'a K, &'a V)>>;
fn into_iter(self) -> Self::IntoIter {
unimplemented!()
}
}
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()
}
}
fn main() {}
serialize_tuple
方法与 serialize_seq
非常相似。Serde 所做的区别是 serialize_tuple
适用于序列,其长度不需要序列化,因为在反序列化时会知道长度。通常的示例是 Rust 的 tuples 和 arrays。在非自描述格式中,Vec<T>
需要以其长度序列化,以便能够将 Vec<T>
再次反序列化。但是 [T; 16]
可以使用 serialize_tuple
进行序列化,因为长度将在反序列化时知道,而无需查看序列化的 bytes。
Serde 区分四种类型的结构体。普通结构体 和 元组结构体 遵循初始化,元素,结束的三步过程,就像 sequence 或 map 一样。 新类型结构体 和 单元结构体 更像基本类型。
#![allow(dead_code)]
struct Color {
r: u8,
g: u8,
b: u8,
}
struct Point2D(f64, f64);
struct Inches(u64);
struct Instance;
fn main() {}
在某些格式中,包括 JSON,struct 和 map 可能看起来相似。Serde 的区别在于 struct 具有在编译时为常量的字符串键,并且这些键在不查看序列化数据的情况下是已知的。这个条件使得某些数据格式能够比 map 更高效和紧凑地处理 struct。
数据格式鼓励将新类型结构体视为内部值的不重要的外壳,只序列化内部值。例如,参见JSON 对新类型结构体的处理。
#![allow(dead_code)]
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,
{
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()
}
}
fn main() {}
序列化 enum variants 与序列化 structs 非常相似。
#[allow(dead_code)]
enum E {
Color { r: u8, g: u8, b: u8 },
Point2D(f64, f64),
Inches(u64),
Instance,
}
fn main() {}
有两个更特殊的情况,属于 Serializer trait 的一部分。
有一个方法 serialize_bytes
,用于序列化 &[u8]
。有些格式将 bytes 视为 seq,但有些格式能够更紧凑地序列化 bytes。目前,Serde 在 Serialize
实现中不使用 serialize_bytes
用于 &[u8]
或 Vec<u8>
,但一旦specialization 在稳定的 Rust 中出现,我们将开始使用它。目前可以使用 serde_bytes
crate 来使得能够通过 serialize_bytes
高效处理 &[u8]
和 Vec<u8>
。
最后,serialize_some
和 serialize_none
对应于 Option::Some
和 Option::None
。用户对 Option
枚举的期望通常与其他枚举不同。Serde JSON 将 Option::None
序列化为 null
,将 Option::Some
仅序列化为包含的值。