我想反序列化一个相当深的JSON到Rust结构:
{
"root": {
"f1": {
"f2": {
"f3": 123
}
}
}
}
当派生Deserialize
时,我将不得不创建太多的结构体-上面的JSON的每个级别一个:
struct Root {
f1: Field1
}
struct Field1 {
f2: Field2
}
struct Field3 {
f3: Field3
}
// ...
有没有什么方法可以避免这个数量的结构体。我没有找到任何属性,这可能对派生有帮助。我想有这样的东西:
struct Root {
// some attr?
f3: u64
}
当然,实现自定义反序列化是可能的,但我想知道,是否有一种默认的方法来实现这一点。
1条答案
按热度按时间sczxawaw1#
我认为这是一个有趣的问题/挑战,所以我写了一个简单的proc-macro属性来完成这个任务,称为
serde_flat_path
。下面是一个如何使用它来提供问题中描述的功能的示例:该属性必须在派生
Serialize
或Deserialize
之前放置,因为它将serde
属性放置在具有#[flat_path(...)]
的字段上。我试图确保该属性尽可能与其他serde属性和helper crate一起使用。它也可以用于更复杂的类型,如下面的类型。对于Serializer
或Deserializer
来说,它看起来应该和实际写出链中的所有结构体没有什么不同。公平的警告,虽然这个proc-macro并不完美。目前它不能处理重叠的扁平化路径,由于宏的方式展开。如果尝试这样做,将发出编译时错误,除非你使用
allow_overlap
功能。在某些情况下,它也会与泛型斗争,但我希望改进这一点。