16 个版本 (重大更新)
0.14.0 | 2024年7月8日 |
---|---|
0.13.0 | 2024年2月7日 |
0.12.0 | 2023年9月1日 |
0.11.0 | 2023年3月27日 |
0.3.3 | 2021年12月30日 |
#11 in #descriptor-set
每月下载量 26,343
在 10 个 crate 中使用 (通过 prost-reflect)
16KB
114 行
prost-reflect
一个扩展了 prost
以支持反射和动态消息的 protobuf 库。
用法
此 crate 提供了对动态 protobuf 消息的支持。当在编译前不知道 protobuf 类型定义时,这些非常有用。
此 crate API 的主要入口点是
DescriptorPool
包裹了 protobuf 编译器输出的FileDescriptorSet
,以提供检查类型定义的 API。DynamicMessage
为由MessageDescriptor
描述的任意 protobuf 消息定义提供编码、解码和反射。
示例 - 解码
DynamicMessage
由于需要消息描述符才能运行,因此没有实现 Default
特性。要将 protobuf 字节流解码为该类型的实例,请使用 DynamicMessage::decode
创建 MessageDescriptor
实例的默认值并将其合并到其中
use prost::Message;
use prost_types::FileDescriptorSet;
use prost_reflect::{DynamicMessage, DescriptorPool, Value};
let pool = DescriptorPool::decode(include_bytes!("file_descriptor_set.bin").as_ref()).unwrap();
let message_descriptor = pool.get_message_by_name("package.MyMessage").unwrap();
let dynamic_message = DynamicMessage::decode(message_descriptor, b"\x08\x96\x01".as_ref()).unwrap();
assert_eq!(dynamic_message.get_field_by_name("foo").unwrap().as_ref(), &Value::I32(150));
示例 - JSON 映射
当启用 serde
特性时,DynamicMessage
可以反序列化为 protobuf 消息定义的 规范 JSON 映射。
use prost::Message;
use prost_reflect::{DynamicMessage, DescriptorPool, Value};
use serde_json::de::Deserializer;
let pool = DescriptorPool::decode(include_bytes!("file_descriptor_set.bin").as_ref()).unwrap();
let message_descriptor = pool.get_message_by_name("package.MyMessage").unwrap();
let json = r#"{ "foo": 150 }"#;
let mut deserializer = Deserializer::from_str(json);
let dynamic_message = DynamicMessage::deserialize(message_descriptor, &mut deserializer).unwrap();
deserializer.end().unwrap();
assert_eq!(dynamic_message.get_field_by_name("foo").unwrap().as_ref(), &Value::I32(150));
示例 - 实现 ReflectMessage
ReflectMessage
接口提供了一个 .descriptor()
方法来获取消息的类型信息。它被用于 DynamicMessage
以及由 prost-types
提供的已知类型。
当启用 derive
功能时,可以为 Message
实现派生。派生宏接受以下参数
名称 | 值 |
---|---|
descriptor_pool | 一个表达式,其解析结果为一个包含消息类型的 DescriptorPool 。描述符应该被缓存以避免重新构建。此参数或 file_descriptor_pool_bytes 必须设置其中之一 |
file_descriptor_pool_bytes | 一个表达式,其解析结果为一个包含编码文件描述符集的 Buf 实现。这将在第一次调用 ReflectMessage::descriptor() 时自动添加到全局描述符池中。 |
message_name | 消息的全名,用于在 DescriptorPool 中查找。 |
use prost::Message;
use prost_reflect::{DescriptorPool, ReflectMessage};
use once_cell::sync::Lazy;
static DESCRIPTOR_POOL: Lazy<DescriptorPool>
= Lazy::new(|| DescriptorPool::decode(include_bytes!("file_descriptor_set.bin").as_ref()).unwrap());
#[derive(Message, ReflectMessage)]
#[prost_reflect(descriptor_pool = "DESCRIPTOR_POOL", message_name = "package.MyMessage")]
pub struct MyMessage {}
let message = MyMessage {};
assert_eq!(message.descriptor().full_name(), "package.MyMessage");
如果您正在使用 prost-build
,则 prost-reflect-build
包提供生成 ReflectMessage
实现的帮助器
prost_reflect_build::Builder::new()
.compile_protos(&["src/package.proto"], &["src"])
.unwrap();
最低支持的 Rust 版本
Rust 1.64 或更高。
最低支持的 Rust 版本可能在将来改变,但将以小版本号的升级方式进行。
许可
根据您的选择,许可协议为以下之一
- Apache License,版本 2.0 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献
除非您明确声明,否则您有意提交给工作并包含在内的任何贡献,根据 Apache-2.0 许可证的定义,将根据上述协议进行双许可,不附加任何额外条款或条件。
依赖
~290–750KB
~18K SLoC