#![forbid(unsafe_code)]
#![warn(missing_docs)]
pub use prost_reflect::{
DescriptorPool, DynamicMessage, EnumDescriptor, FieldDescriptor, FileDescriptor,
MessageDescriptor, MethodDescriptor, ServiceDescriptor, UnknownField,
};
pub use prost_reflect::Value as ReflectValue;
pub use prost_reflect::ReflectMessage;
pub mod dynamic;
pub use dynamic::{clear_field, get_field_by_name, has_field, set_field_by_name, unknown_fields};
pub mod native;
pub use native::{
Cardinality as NativeCardinality, DescriptorPool as NativeDescriptorPool,
DynamicMessage as NativeDynamicMessage, EnumDescriptor as NativeEnumDescriptor,
EnumValueDescriptor as NativeEnumValueDescriptor, FieldDescriptor as NativeFieldDescriptor,
FileDescriptor as NativeFileDescriptor, Kind as NativeKind, MapKey as NativeMapKey,
MessageDescriptor as NativeMessageDescriptor, MethodDescriptor as NativeMethodDescriptor,
NativeJsonError, NativeTextError, OneofDescriptor as NativeOneofDescriptor,
ServiceDescriptor as NativeServiceDescriptor, Value as NativeValue,
};
use prost::Message;
use prost_types::FileDescriptorSet;
#[derive(Debug)]
pub enum ReflectError {
Decode(prost::DecodeError),
Pool(String),
NotFound(String),
Field(String),
}
impl std::fmt::Display for ReflectError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ReflectError::Decode(e) => write!(f, "failed to decode FileDescriptorSet: {e}"),
ReflectError::Pool(e) => write!(f, "failed to build DescriptorPool: {e}"),
ReflectError::NotFound(name) => write!(f, "'{name}' not found in pool"),
ReflectError::Field(msg) => write!(f, "field error: {msg}"),
}
}
}
impl std::error::Error for ReflectError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
ReflectError::Decode(e) => Some(e),
ReflectError::Pool(_) | ReflectError::NotFound(_) | ReflectError::Field(_) => None,
}
}
}
impl From<oxiproto_core::OxiProtoError> for ReflectError {
fn from(e: oxiproto_core::OxiProtoError) -> Self {
ReflectError::Pool(e.to_string())
}
}
impl From<ReflectError> for oxiproto_core::OxiProtoError {
fn from(e: ReflectError) -> Self {
oxiproto_core::OxiProtoError::ParseError(e.to_string())
}
}
pub fn pool_from_fds_bytes(fds_bytes: &[u8]) -> Result<DescriptorPool, ReflectError> {
let fds = FileDescriptorSet::decode(fds_bytes).map_err(ReflectError::Decode)?;
DescriptorPool::from_file_descriptor_set(fds).map_err(|e| ReflectError::Pool(e.to_string()))
}
pub fn pool_from_fds(fds: FileDescriptorSet) -> Result<DescriptorPool, ReflectError> {
DescriptorPool::from_file_descriptor_set(fds).map_err(|e| ReflectError::Pool(e.to_string()))
}
pub fn dynamic_message(
pool: &DescriptorPool,
full_name: &str,
) -> Result<DynamicMessage, ReflectError> {
let msg_desc = pool
.get_message_by_name(full_name)
.ok_or_else(|| ReflectError::NotFound(full_name.to_owned()))?;
Ok(DynamicMessage::new(msg_desc))
}
pub fn get_service_by_name(pool: &DescriptorPool, full_name: &str) -> Option<ServiceDescriptor> {
pool.get_service_by_name(full_name)
}
pub fn get_enum_by_name(pool: &DescriptorPool, full_name: &str) -> Option<EnumDescriptor> {
pool.get_enum_by_name(full_name)
}
pub fn all_messages(pool: &DescriptorPool) -> impl Iterator<Item = MessageDescriptor> + '_ {
pool.all_messages()
}
pub fn all_services(pool: &DescriptorPool) -> impl Iterator<Item = ServiceDescriptor> + '_ {
pool.services()
}