如何为外部类型实现serde的Serialize和Deserialize traits?

10

我正在尝试为一个外部枚举实现SerializeDeserialize,但我不知道该怎么做。它有From<u64>,所以我只想让这个对象用那个来序列化。

#[derive(Serialize, Deserialize)]
pub struct ImageBinds {
    binds: HashMap<KeybdKey, Vec<u8>>, // KeybdKey doesn't implement serialize
}

// won't compile with this:
// only traits defined in the current crate can be implemented for arbitrary types
// impl doesn't use only types from inside the current crate
// I understand the orphan rule and all that but I have no idea how else I'd implement it
// I've looked at serde remote stuff and I cannot work out how to do it with an enum without
// literally just copying the whole crate into my scope which is stupid
impl Serialize for KeybdKey {
    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        serializer.serialize_u64(u64::from(*self))
    }
}

KeybdKey来自于 inputbot 包。


1
这个教程对你有帮助吗?链接 - user4815162342
最好包括准确的错误信息,甚至在 Rust Playground 中提供可重现的案例:https://play.rust-lang.org/ - Ultrasaurus
1
如果你的类型嵌套在 HashMap 中,远程推导功能将无法帮助你。你可以使用自定义反序列化 HashMap(即 with 属性),一个包装类型或者尝试 serde_with 箱来解决此问题。文档中只提到了 From<KeybdKey> for u64,但没有 From<u64>。因此,这样只能让您编写序列化代码,但不能进行反序列化。 - jonasbb
1个回答

3

正确的方法是使用Newtype模式。通过将外部类型包装在Newtype中,可以为其实现trait。

您的示例将使用以下代码正常工作:

#[derive(Serialize, Deserialize)]
pub struct ImageBinds {
    binds: HashMap<MyKeybdKey, Vec<u8>>,
}

// This is a Newtype containing the external type .
struct MyKeybdKey(KeybdKey);

impl Serialize for MyKeybdKey {
    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        serializer.serialize_u64(u64::from(self.0))
    }
}

impl<'de> Deserialize<'de> for MyKeybdKey {
    fn deserialize<D: Deserializer>(deserializer: D) -> Result<Self, D::Error> {
        // ...deserialize implementation.
    }
}

我没有填写Deserialize 实现,因为它会相当长,但基本概念是只需反转Serialize 实现中所依赖的From 实现。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接