greathongtu 的 Blog

Serde

序列化过程

首先通过 macro 为 struct 实现 impl Serialize。 在 impl 的 serialize 方法里,通过了解的结构信息(struct 有哪些 field,field 具体名称和类型等信息)调用对应的 Serializer 的方法。 也就是说 Serialize 负责控制如何将 Rust 数据结构转变为 serde data model(并不是真正的转变,只是控制如何转变:也就是如何调用 Serializer)。Serializer 负责具体执行(如serialize_i32, serialize_struct 方法等),将 serde data model 转变为具体的目标 format。 其中 Serializer 的实现一般在另一个库如 serde_json 里。 这也是为什么说 serde 库并不是 parse 库。

impl _serde::Serialize for Test {
    fn serialize<__S>(
        &self,
        __serializer: __S,
    ) -> _serde::__private::Result<__S::Ok, __S::Error>
    where
        __S: _serde::Serializer,
    {
        let mut __serde_state = _serde::Serializer::serialize_struct(
            __serializer,
            "Test",
            false as usize + 1 + 1,
        )?;
        _serde::ser::SerializeStruct::serialize_field(
            &mut __serde_state,
            "test_num",
            &self.test_num,
        )?;
        _serde::ser::SerializeStruct::serialize_field(
            &mut __serde_state,
            "test_str",
            &self.test_str,
        )?;
        _serde::ser::SerializeStruct::end(__serde_state)
    }
}

反序列化过程

首先通过 macro 为 struct 实现 impl Deserialize。 在 impl 的 deserialize 方法内,通过了解的信息调用相应的 deserializer_xxx 方法,对于 json 这样的自描述格式,直接调用 deserializer_any 方法就可以。同时还传递了一个 Visitor 进去,用来进行真正的反序列化工作。Visitor 的 associated type 就是最终反序列化的目标 Rust 数据结构格式,实现了 visit_seq、 visit_map 等方法用来给 Deserializer 调用。

Visitor 是 Deserialize 这一侧实现的,用来将 serde data model 转变为 Rust 数据结构。Vistor 的调用者 deserializer.deserializer_xxx 是 Deserializer 这一侧实现的,一般在另一个库如 serde_json 里,用来将不同的具体 format 转变为 serde data model。

还有辅助 FieldVisitor 的实现,用来帮助获取 map 的 key 信息。

// Deserialize::deserialize 方法
const FIELDS: &'static [&'static str] = &[
    "test_num",
    "test_str",
    "test_vector",
];
_serde::Deserializer::deserialize_struct(
    __deserializer,
    "Test",
    FIELDS,
    __Visitor {
        marker: _serde::__private::PhantomData::<Test>,
        lifetime: _serde::__private::PhantomData,
    },
)
// serde_json 的 deserialize_map 方法
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where
    V: de::Visitor<'de>,
{
    let peek = match tri!(self.parse_whitespace()) {
        Some(b) => b,
        None => {
            return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
        }
    };

    let value = match peek {
        b'{' => {
            check_recursion! {
                self.eat_char();
                let ret = visitor.visit_map(MapAccess::new(self));
            }

            match (ret, self.end_map()) {
                (Ok(ret), Ok(())) => Ok(ret),
                (Err(err), _) | (_, Err(err)) => Err(err),
            }
        }
        _ => Err(self.peek_invalid_type(&visitor)),
    };

    match value {
        Ok(value) => Ok(value),
        Err(err) => Err(self.fix_position(err)),
    }
}