1 个不稳定版本
0.1.0 | 2021年8月11日 |
---|
#64 in #prost
在 autoproto 中使用
70KB
2K SLoC
Autoproto
该crate实现了一个自定义派生宏,用于 prost::Message
特性,并包含一些辅助特性,以便尽可能简化自动派生的过程——基本上是在类型系统中添加更多信息,而不是在宏实现中添加。如果宏没有执行您需要的操作,您可以实现“基础特性”之一,如 ProtoStruct
和 ProtoOneof
,并使用 generic
模块中的函数来实现其余的特性。
限制
(目前)不支持结构体内嵌 oneof
这最终可以解决,但目前此派生宏的一个主要限制是不能支持像这样的 Protobuf 类型
message Foo {
string first = 1;
oneof some_oneof {
string second = 2;
string third = 3;
}
}
按照库的当前编写方式,它只有在消息是唯一成员时才支持 oneof
。
不能从 .proto
文件自动生成
这是与 prost
的最大区别,也是一项故意选择。我认为从 Protobuf 文件自动生成 Rust 文件至少部分是 prost
的一个错误特性,因为对于许多情况,它会导致 Rust 中的类型变得极其难以管理。Rust 拥有一个深入且丰富的类型系统,而 Protobuf 无法很好地表示它。最终我希望有编译时检查,以确保 Rust 类型与给定的 Protobuf 文件兼容,但目前此功能尚未实现。
与 #[derive(prost::Message)]
的改进和变更
支持更多类型作为字段
此宏支持除了 Vec
以外的集合用于重复字段,结构体中的裸枚举,usize
/isize
,以及映射。对于重复集合,任何实现了 std::iter::Extend
并可以遍历其引用类型的类型都可以用作结构体中的集合。目前,你必须手动实现 Proto
和 ProtoEncode
为这些类型,但如果 feature(specialization)
被稳定化,这个限制有望被解除。
虽然目前我们无法自动支持任何实现 proto::Message
的类型作为字段 - 因为该特质是为标量实现的,我们之所以有我们自己的特质,是为了能对标量有不同实现 - 你只需实现 IsMessage
标记特质,就可以允许该类型作为 #[derive)]
类型的字段。
此外,消息不再需要被包装在 Option
中,因为 protobuf 的 eager decoding 已经要求所有消息实现 Default
。如果你想区分字段是否提供了默认值或完全没有提供,可以将任何类型包装在 Option
中。
为更多类型的推导
此宏允许为几乎任何标记联合和泛型结构体进行推导。例如
# #![feature(generic_associated_types)]
#[derive(Copy, Clone, PartialEq, Debug, autoproto::Message)]
enum Oneof<A, B, C> {
Nothing,
One(A),
Two(A, B),
Three(A, B, C),
}
不允许混合标记-非标记结构体
prost
宏的一个变化是,字段要么都必须是标记的,要么都不能是标记的。例如,以下两个是可以的
# #![feature(generic_associated_types)]
#[derive(Copy, Clone, PartialEq, Default, Debug, autoproto::Message)]
struct SomeStructTagged<A, B, C, D, E> {
#[autoproto(tag = 1)]
a: A,
#[autoproto(tag = 2)]
b: B,
#[autoproto(tag = 3)]
c: C,
#[autoproto(tag = 4)]
d: D,
#[autoproto(tag = 5)]
e: E,
}
#[derive(Copy, Clone, PartialEq, Default, Debug, autoproto::Message)]
struct SomeStruct<A, B, C, D, E> {
a: A,
b: B,
c: C,
d: D,
e: E,
}
但是以下这个不行
# #![feature(generic_associated_types)]
#[derive(Copy, Clone, PartialEq, Default, Debug, autoproto::Message)]
struct SomeStruct<A, B, C, D, E> {
a: A,
b: B,
#[autoproto(tag = 1)]
c: C,
d: D,
e: E,
}
依赖关系
~1.5MB
~37K SLoC