#protobuf #serialization #json #prost #dynamic #message #definition

prost-reflect-build

用于与prost-build和prost-reflect一起使用,以生成ReflectMessage实现的实用函数

8个重大版本

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.6.0 2022年3月14日

#1127 in 编码

Download history 3048/week @ 2024-05-03 3845/week @ 2024-05-10 3582/week @ 2024-05-17 3364/week @ 2024-05-24 3771/week @ 2024-05-31 3533/week @ 2024-06-07 3698/week @ 2024-06-14 5013/week @ 2024-06-21 4111/week @ 2024-06-28 4510/week @ 2024-07-05 4774/week @ 2024-07-12 5407/week @ 2024-07-19 4659/week @ 2024-07-26 5125/week @ 2024-08-02 5796/week @ 2024-08-09 4019/week @ 2024-08-16

20,832 每月下载次数
用于 8 个crate(2 直接)

MIT/Apache

545KB
12K SLoC

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

The ReflectMessage trait 提供了一个 .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 crate 提供了生成 ReflectMessage 实现的帮助器

prost_reflect_build::Builder::new()
    .compile_protos(&["src/package.proto"], &["src"])
    .unwrap();

最低支持的 Rust 版本

Rust 1.64 或更高。

最低支持的 Rust 版本可能会在未来更改,但将通过小版本号升级来完成。

许可证

许可协议为以下之一:

任选其一。

贡献

除非您明确声明,否则任何有意提交以包含在您的工作中的贡献,根据 Apache-2.0 许可证定义,均应双重许可如上,不附加任何额外条款或条件。

依赖项

~8–18MB
~249K SLoC