#deserialize #traits #serialization #key #object #deserializer #erased

keyedes

通过允许用户将键编码到格式中,帮助序列化和反序列化特例对象。

1 个不稳定版本

0.1.0 2021年8月8日

#2052编码

MIT 许可证

29KB
578

键控反序列化

这个crate旨在通过允许用户将键编码到可序列化的格式中,然后在使用反序列化时使用这些格式来帮助序列化和反序列化不同的对象。它主要提供 serialize_with_key()deserialize_by_key() 来实现这一点。

主要动机是特例对象的反序列化。如果你有选择的话,typetag crate更容易使用,而此crate则更加手动。


示例用法

use serde::{Deserialize, Serialize};

trait TestTrait: erased_serde::Serialize {
    fn key(&self) -> &'static str;
}

mod test_trait {
    use std::collections::HashMap;
    use std::ops::Deref;
    use keyedes::DesFnSync;
    use once_cell::sync::Lazy;
    use serde::{Deserializer, Serializer};
    use super::TestTrait;

    static MAP: Lazy<HashMap<String, DesFnSync<Box<dyn TestTrait>>>> =
        Lazy::new(|| {
            let mut map = HashMap::<String, DesFnSync<Box<dyn TestTrait>>>::new();
            // fill out the map
            map
        });

    pub(super) fn serialize<S>(value: &Box<dyn TestTrait>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        keyedes::serialize_with_key(
            "Box<dyn TestTrait>",
            &["id", "data"],
            value.key(),
            value.deref(),
            serializer,
        )
    }

    pub(super) fn deserialize<'de, D>(deserializer: D) -> Result<Box<dyn TestTrait>, D::Error>
    where
        D: Deserializer<'de>,
    {
        keyedes::deserialize_by_key(
            "Box<dyn TestTrait>",
            &["id", "data"],
            |key: String, deserializer| {
                MAP.get(&key)
                    .ok_or_else(keyedes::unknown_key)
                    .and_then(|f| f(deserializer))
            },
            deserializer,
        )
    }
}

#[derive(Serialize, Deserialize)]
struct Wrapper {
    #[serde(with = "test_trait")]
    test: Box<dyn TestTrait>,
}

依赖关系

~475–770KB
~17K SLoC