3 个版本
0.1.2 | 2021 年 8 月 27 日 |
---|---|
0.1.1 | 2021 年 8 月 17 日 |
0.1.0 | 2021 年 8 月 11 日 |
#933 在 Rust 模式
70KB
2K SLoC
Autoproto
此 crate 实现了对 prost::Message
特性的自定义 derive 宏,同时包含一些辅助特性以尽可能简化自动推导 - 基本上是将更多信息放入类型系统中而不是宏实现中。如果宏没有执行您需要的操作,您可以实现“基础特性”之一,如 ProtoStruct
和 ProtoOneof
,并使用 generic
模块中的函数来实现其余特性。
限制
(目前) 不支持嵌套在结构体中的 oneof
这最终可以解决,但现在是此 derive 宏的一个主要限制,因为我们不能支持像这样使用 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 的急切解码已经要求所有消息实现 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,
}
依赖关系
~2MB
~46K SLoC