给第三方库的类型添加序列化属性

6

我正在尝试为我的Rust结构体添加序列化功能。这是一个日历事件,代码如下:

#[derive(PartialEq, Clone, Encodable, Decodable)]
pub struct Event {
    pub id: Uuid,
    pub name: String,
    pub desc: String,
    pub location: String,
    pub start: DateTime<Local>,
    pub end: DateTime<Local>,
}

该结构使用了第三方的两种不同类型,Uuid 来自https://github.com/rust-lang/uuidDateTime 来自https://github.com/lifthrasiir/rust-chrono

如果我尝试构建项目,编译器会抱怨找不到 UuidDateTimeencode 函数,这是因为它们都没有从 serialize crate 派生出 EncodableDecodable

那么问题来了: 有没有一种方法可以在不触及库本身代码的情况下添加派生到第三方结构体上?如果没有,那么在这种情况下添加序列化功能的最佳方法是什么?

2个回答

5
首先,您不应该使用EncodableDecodable;您需要使用来自rustc-serialize包的RustcEncodableRustcDecodable
其次,您无法这样做。如果您没有编写所涉及的类型或特性,则无法这样做:这是编译器的故意保证。(另请参见“一致性”)
在这种情况下,您可以采取两种方法:
1.手动实现特性。有时,派生不起作用,因此您必须手动编写特性实现。在这种情况下,它将为您直接手动实现不支持类型的编码/解码提供机会。
2.包装不支持的类型。这意味着要执行类似于struct UuidWrap(pub Uuid);的操作。这为您提供了一个新类型,即您编写的类型,这意味着您可以...好吧,执行第一步,但仅对少量代码执行第一步。当然,现在您必须包装和解包UUID,这有点麻烦。

1
如果他使用serde呢?serde难道不是使用Encodable/Decodable吗? - Daniel Fath
从存储库的文档中可以看出,它没有使用相同的特征。此外,他们特别提到了 serialize crate。无论如何,如果他们确实使用了 Serde,他们应该这样说,否则答案将没有用处。 :) - DK.
“serialize”和“rustc-serialize”有什么区别? - 0kp
@0kp 其中一个是编译器内部使用的,不应该被其他人使用;另一个则在 crates.io 上,可以被其他人使用。出于某些当时看起来有道理的原因,它们分别是 serializerustc-serialize就是这个顺序。不,真的。是的,我知道看起来很奇怪。 - DK.

1

在寻找同样问题的解决方案时,我发现了这个问题。Chrono已启用rustc-serialize支持。您需要通过添加以下依赖项来启用它。

[dependencies.chrone]
version = "*"
features = ["rustc-serialize"]

我从ker对我的question的回答中了解到这个。希望对你有所帮助。


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