我们这章带大家实现Desialize,接着我们之前讲的继续我们的serde之旅。
实现Deserialize
Deserialize trait如下所示:
pub trait Deserialize<'de>:Sized{
fn deserialize<D>(deserializer:D) ->Result<Self,D::Error> where D:Deserializer<'de>;
}
这个方法的作用是通过为Deserializer 提供一个Visitor,将类型映射到Serde数据类型,然后由Deserializer 驱动 Visitor 来构建类型的实例。
在大多数情况下,Serde的derive能够为你的crate中定义的struct和enum生成适当的Deserialize实现。如果你需要对某种类型的序列化为进行自定义,而派生不支持该行为,可以自己实现Deserialize。实现Deserialize对于类型而言比实现Serialize更加复杂。
Deserializer trait 支持两种入口样式,从而实现不同种类的反序列化。
- deserialize_any方法。述像JSON 这样的自描述数据格式能够查看序列化数据并判断其代表的内容。例如,JSON 反序列化器可能看到一个左花括号 ({) 并知道它看到的是一个 map。如果数据格式支持 Deserializer::deserialize_any,它将根据 input 中判断的类型来驱动 Visitor。JSON 在反序列化 serde_json::Value 时使用了这种方法,它是能够表示任何 JSON 文档的 enum。不需要知道 JSON 文档中的内容是什么,我们也可以通过 Deserializer::deserialize_any 将其反序列化为 serde_json::Value。
- 其他各种 deserialize_* 方法。非自描述格式例如 Postcard 需要告诉输入中包含的是什么内容才能对其进行反序列化。deserialize_* 方法是为反序列器提供关于如何解释下一个输入片段的提示。非自描述格式无法对类似serde_json::Value 这样依赖 Deserializer::deserialize_any 的内容进行反序列化。
在实现 Deserialize 时,应避免依赖Deserializer::deserialize_any,除非需要反序列化器告诉您输入中的类型。要知道,依赖Deserializer::deserialize_any 意味着您的数据类型只能从自描述格式中反序列化,排除了 Postcard 等许多其他格式。
下面我们看看Visitor trait
Visitor trait
Visitor是由Deserialize实例化冰传递给Deserializer的。然后,Deserializer会调用Visitor上的方法来构造所需要的类型。
我们来看Visitor示例,能够从各种类型中反序列化基本的i32。
use std::fmt;
use serde::de::{self, Visitor};
struct I32Visitor;
impl<'de> Visitor<'de> for I32Visitor {
type Value = i32;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an integer between -2^31 and 2^31")
}
fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(i32::from(value))
}
fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(value)
}
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where
E: de::Error,
{
use std::i32;
if value >= i64::from(i32::MIN) && value <= i64::from(i32::MAX) {
Ok(value as i32)
} else {
Err(E::custom(format!("i32 out of range: {}", value)))
}
}
// 其他方法类似:
// - visit_i16
// - visit_u8
// - visit_u16
// - visit_u32
// - visit_u64
}
Visitor trait 还有许多没有为I32Visitor实现的方法。如果调用这些方法,将返回类型错误。例如,I32Visitor没有实现Visitor::visit_map,因此尝试在输入包含映射时反序列化一个i32 是一个类型错误。
序列化自定义map类型
use std::fmt;
use std::marker::PhantomData;
use serde::de::{Deserialize, Deserializer, Visitor, MapAccess};
// Visitor 是一个类型,其中包含 Deserializer 可以根据输入数据的内容驱动的方法。
//
// 在 map 的情况下,我们需要泛型类型参数 K 和 V 来正确设置输出类型,但不需要任何状态。
// 这是 Rust 中的 “零大小类型” 的一个例子。PhantomData
// 防止编译器因未使用的泛型类型参数而抱怨。
struct MyMapVisitor<K, V> {
marker: PhantomData<fn() -> MyMap<K, V>>
}
impl<K, V> MyMapVisitor<K, V> {
fn new() -> Self {
MyMapVisitor {
marker: PhantomData
}
}
}
// 这是Deserializers将驱动的特质。每种类型的数据都有一个与之对应的方法
// 我们的类型知道如何从中反序列化。这里有许多其他未在此处实现的方法,例如从整数或字符串反序列化。
// 默认情况下,这些方法将返回错误,这是有道理的,因为我们无法从整数或字符串反序列化MyMap。
impl<'de, K, V> Visitor<'de> for MyMapVisitor<K, V>
where
K: Deserialize<'de>,
V: Deserialize<'de>,
{
//我们的Visitor将生成的类型。
type Value = MyMap<K, V>;
//格式化一条消息,说明该 Visitor 希望接收哪些数据。
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("一个非常特殊的 map")
}
// 从Deserializer提供的抽象“地图”中反序列化MyMap。MapAccess输入是Deserializer提供的回调,让我们可以看到地图中的每个条目。
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let mut map = MyMap::with_capacity(access.size_hint().unwrap_or(0));
// 在输入中还有条目时,将它们添加到我们的地图中。
while let Some((key, value)) = access.next_entry()? {
map.insert(key, value);
}
Ok(map)
}
}
// 这是告诉 Serde 如何反序列化 MyMap 的特质。
impl<'de, K, V> Deserialize<'de> for MyMap<K, V>
where
K: Deserialize<'de>,
V: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
//实例化我们的 Visitor,并要求 Deserializer 在输入数据上驱动它,从而生成 MyMap 的实例。
deserializer.deserialize_map(MyMapVisitor::new())
}
}
反序列化strcut
struct Duration {
secs: u64,
nanos: u32,
}
use std::fmt;
use serde::de::{self, Deserialize, Deserializer, Visitor, SeqAccess, MapAccess};
impl<'de> Deserialize<'de> for Duration {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
enum Field { Secs, Nanos }
// This part could also be generated independently by:
//
// #[derive(Deserialize)]
// #[serde(field_identifier, rename_all = "lowercase")]
// enum Field { Secs, Nanos }
impl<'de> Deserialize<'de> for Field {
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`secs` or `nanos`")
}
fn visit_str<E>(self, value: &str) -> Result<Field, E>
where
E: de::Error,
{
match value {
"secs" => Ok(Field::Secs),
"nanos" => Ok(Field::Nanos),
_ => Err(de::Error::unknown_field(value, FIELDS)),
}
}
}
deserializer.deserialize_identifier(FieldVisitor)
}
}
struct DurationVisitor;
impl<'de> Visitor<'de> for DurationVisitor {
type Value = Duration;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct Duration")
}
fn visit_seq<V>(self, mut seq: V) -> Result<Duration, V::Error>
where
V: SeqAccess<'de>,
{
let secs = seq.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
let nanos = seq.next_element()?
.ok_or_else(|| de::Error::invalid_length(1, &self))?;
Ok(Duration::new(secs, nanos))
}
fn visit_map<V>(self, mut map: V) -> Result<Duration, V::Error>
where
V: MapAccess<'de>,
{
let mut secs = None;
let mut nanos = None;
while let Some(key) = map.next_key()? {
match key {
Field::Secs => {
if secs.is_some() {
return Err(de::Error::duplicate_field("secs"));
}
secs = Some(map.next_value()?);
}
Field::Nanos => {
if nanos.is_some() {
return Err(de::Error::duplicate_field("nanos"));
}
nanos = Some(map.next_value()?);
}
}
}
let secs = secs.ok_or_else(|| de::Error::missing_field("secs"))?;
let nanos = nanos.ok_or_else(|| de::Error::missing_field("nanos"))?;
Ok(Duration::new(secs, nanos))
}
}
const FIELDS: &'static [&'static str] = &["secs", "nanos"];
deserializer.deserialize_struct("Duration", FIELDS, DurationVisitor)
}
}
最后希望大家多关注我的公众号哈:花说编程