#protobuf #json #serialization #macro-derive #file-descriptor #descriptor-set

prost-reflect-derive

用于生成 ReflectMessage 实现的 derive 宏

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

Download history 4698/week @ 2024-05-05 5224/week @ 2024-05-12 5050/week @ 2024-05-19 4544/week @ 2024-05-26 4689/week @ 2024-06-02 4939/week @ 2024-06-09 5001/week @ 2024-06-16 6434/week @ 2024-06-23 4854/week @ 2024-06-30 6091/week @ 2024-07-07 6194/week @ 2024-07-14 6659/week @ 2024-07-21 6467/week @ 2024-07-28 6367/week @ 2024-08-04 7613/week @ 2024-08-11 5536/week @ 2024-08-18

每月下载量 26,343
10 个 crate 中使用 (通过 prost-reflect)

MIT/Apache

16KB
114

crates.io docs.rs deps.rs MSRV Continuous integration codecov.io Apache 2.0 OR MIT licensed

prost-reflect

一个扩展了 prost 以支持反射和动态消息的 protobuf 库。

用法

此 crate 提供了对动态 protobuf 消息的支持。当在编译前不知道 protobuf 类型定义时,这些非常有用。

此 crate API 的主要入口点是

示例 - 解码

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-2.0 许可证的定义,将根据上述协议进行双许可,不附加任何额外条款或条件。

依赖

~290–750KB
~18K SLoC