A protobuf library extending prost
with reflection support and dynamic messages.
This crate provides support for dynamic protobuf messages. These are useful when the protobuf type definition is not known ahead of time.
The main entry points into the API of this crate are:
DescriptorPool
] wraps a FileDescriptorSet
output by
the protobuf compiler to provide an API for inspecting type definitions.DynamicMessage
] provides encoding, decoding and reflection of an arbitrary protobuf
message definition described by a [MessageDescriptor
].DynamicMessage
does not implement [Default
] since it needs a message descriptor to
function. To decode a protobuf byte stream into an instance of this type, use [DynamicMessage::decode
]
to create a default value for the MessageDescriptor
instance and merge into it:
```rust use prost::Message; use prosttypes::FileDescriptorSet; use prostreflect::{DynamicMessage, DescriptorPool, Value};
let pool = DescriptorPool::decode(includebytes!("filedescriptorset.bin").asref()).unwrap(); let messagedescriptor = pool.getmessagebyname("package.MyMessage").unwrap();
let dynamicmessage = DynamicMessage::decode(messagedescriptor, b"\x08\x96\x01".as_ref()).unwrap();
asserteq!(dynamicmessage.getfieldbyname("foo").unwrap().asref(), &Value::I32(150)); ```
When the serde
feature is enabled, DynamicMessage
can be deserialized to and from the
canonical JSON mapping
defined for protobuf messages.
```rust use prost::Message; use prostreflect::{DynamicMessage, DescriptorPool, Value}; use serdejson::de::Deserializer;
let pool = DescriptorPool::decode(includebytes!("filedescriptorset.bin").asref()).unwrap(); let messagedescriptor = pool.getmessagebyname("package.MyMessage").unwrap();
let json = r#"{ "foo": 150 }"#; let mut deserializer = Deserializer::fromstr(json); let dynamicmessage = DynamicMessage::deserialize(message_descriptor, &mut deserializer).unwrap(); deserializer.end().unwrap();
asserteq!(dynamicmessage.getfieldbyname("foo").unwrap().asref(), &Value::I32(150)); ```
ReflectMessage
The [ReflectMessage
] trait provides a .descriptor()
method to get type information for a message. By default it is just implemented for DynamicMessage
.
When the reflect-well-known-types
feature is enabled, it is implemented for the well-known-types provided by prost-types
.
When the derive
feature is enabled, it can be derived for Message
implementations. The
derive macro takes the following parameters:
| Name | Value |
|-----------------|-------|
| descriptorpool | An expression that resolves to a [DescriptorPool
] containing the message type. The descriptor should be cached to avoid re-building it. |
| messagename | The full name of the message, used to look it up within [DescriptorPool
]. |
```rust use prost::Message; use prostreflect::{DescriptorPool, ReflectMessage}; use oncecell::sync::Lazy;
static DESCRIPTORPOOL: Lazy
pub struct MyMessage {}
let message = MyMessage {}; asserteq!(message.descriptor().fullname(), "package.MyMessage"); ```
If you are using prost-build
, the prost-reflect-build
crate provides helpers to generate ReflectMessage
implementations:
rust,no_run
prost_reflect_build::Builder::new()
.compile_protos(&["src/package.proto"], &["src"])
.unwrap();
Rust 1.56 or higher.
The minimum supported Rust version may be changed in the future, but it will be done with a minor version bump.
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.