1 个不稳定版本
新 0.3.0 | 2024年8月19日 |
---|
55 在 #prost
每月135 次下载
用于 prost-convert
26KB
483 代码行
Prost convert derive
此crate提供了用于TryFromProto
和FromNative
特质的derive宏。
使用它所需的内容。
- Proto结构/枚举和本地结构应具有相同的名称。
- Proto结构/枚举和本地结构应具有相同的字段名称。
用例:移除不需要的选项
Prost将用户定义的消息包装为可选的,如proto3规范所述。
宏的一个想法是,如果proto结构中的字段是可选的,而本地结构中没有,则提供一个转换函数以尝试进行转换。
遗憾的是,在derive宏中我们无法知道proto结构字段是否为可选的。我们只知道结构路径,我们无法简单地解析它。
因此,如果我们使用TryFrom<Option<T>> for T
,则无法自定义行为,因为我们不知道它是否为可选的。
一种解决方案是提供
#[required]
属性在本地结构上的字段,但这很冗长,并增加了样板。
除了TryFrom<Option<T>> for T
之外,由于孤儿规则,这不是可实现的。
例如,这将不起作用
let option = Some(String::from("foo"));
let string: String = o.try_into()?;
因此,我们创建了自己的trait,以便在将Opion<T>
转换为T时定义要执行的操作。
用例:移除不需要的包装器
我们真正需要的是将包装器转换为网络传输。通过网络接收后,再从包装器中创建。因此,我们必须指定包装器路径。但是,从包装器路径我们不能推导出包装路径,反之亦然。如果本地是枚举类型,我们能否假设提供的源是一个只有枚举类型字段的struct?-> 不能。目前我们需要为每个嵌套struct实现ProstConvert。所以我们可以有不在包装器struct内部的枚举。如果包装器只是递归调用,也许可以不提供包装器?
枚举的语法
#[derive(ProstConvert)]
#[prost_convert(src = "proto::Foo", wrapper = "proto::FooWrapper")]
enum Foo {
Foo1,
Foo2,
}
这将生成2个TryFromProto
实现: "src" 属性与struct的用法相同,它会生成
impl TryFromProto<proto::Foo> for Foo
impl FromNative<Foo> for proto::Foo
但是,"wrapper" 属性还会生成2个额外的转换函数,与包装器struct一起
impl TryFromProto<proto::FooWrapper> for Foo
impl FromNative<Foo> for proto::FooWrapper
如果你使用了包装器关键字,不需要为包装器本身派生 ProstConvert
。换句话说,我们不需要
impl TryFromProto<proto::FooWrapper> for FooWrapper
impl FromNative<FooWrapper> for proto::FooWrapper
目前
- 包装器只能用于枚举(容易为struct实现,但是有没有用例?)
- 包装器假设包装器是一个包含一个枚举的单字段struct。
潜在改进
- 目前这个宏同时实现了
TryFromProto
和FromNative
,但有时我们可能只需要其中一个。 - 只需使用darling解析宏参数(检查它是否与
syn::Error
集成良好)。 - 当字段未实现prost derive时,编译错误应在字段上,而不是在struct上(例如缺少Debug、Clone等)。
- 当
[prost_convert(src = "..."
]出现在struct注释顶部时,将出现编译错误 => 不应该是这种情况。 - 我们是否使用了所有的错误变体?
- 确认
Style::Tuple
和Style::Tuple
不能从protobuf创建。 - 如果需要,提供自定义实现?例如,从
std::string
创建std::net::IpAddress
。 - 处理新类型
struct Id(Uuid)
。 - 处理元组
struct Foo(i32, i32)
。 - 为这个添加UT
pub struct Message {}
- 处理"struct"枚举变体或在文档中标记它。另外,如果我们不支持它,我们可以在宏上添加编译错误。
许可证
根据以下任一许可证授权:
- Apache License, Version 2.0 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT许可(《LICENSE-MIT》或https://open-source.org.cn/licenses/MIT)
由您选择。
贡献
除非您明确声明,否则根据Apache-2.0许可证定义的任何有意提交以包含在作品中的贡献,将如上双重许可,不附加任何额外条款或条件。
依赖项
~1.5MB
~35K SLoC