#protobuf #serialization #json #serde-json #protobuf-compiler #descriptor-set #codec

prost-reflect

一个扩展 prost 的具有反射支持和动态消息功能的 protobuf 库

40 个版本

0.14.0 2024 年 7 月 8 日
0.13.0 2024 年 2 月 7 日
0.12.0 2023 年 9 月 1 日
0.11.4 2023 年 4 月 28 日
0.3.3 2021 年 12 月 30 日

#42 in 编码

Download history 75316/week @ 2024-05-04 87263/week @ 2024-05-11 80408/week @ 2024-05-18 72734/week @ 2024-05-25 88619/week @ 2024-06-01 85034/week @ 2024-06-08 80367/week @ 2024-06-15 69912/week @ 2024-06-22 63490/week @ 2024-06-29 76283/week @ 2024-07-06 64488/week @ 2024-07-13 82112/week @ 2024-07-20 85210/week @ 2024-07-27 81644/week @ 2024-08-03 89797/week @ 2024-08-10 66949/week @ 2024-08-17

340,534 月下载量
用于 109 个 crate(直接使用 13 个)

MIT/Apache

530KB
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

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-buildprost-reflect-build软件包提供了生成ReflectMessage实现的辅助工具。

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

最低支持的Rust版本

Rust 1.64或更高版本。

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

许可协议

许可协议为以下之一

任选其一。

贡献

除非您明确声明,否则根据Apache-2.0许可协议定义,您有意提交的任何贡献,将按上述方式双许可,没有任何额外的条款或条件。

依赖关系

~0.4–1.3MB
~15K SLoC