Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 43 additions & 6 deletions rustecal-types-protobuf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! Provides support for Protobuf message serialization with rustecal.

use prost::Message;
use prost_reflect::ReflectMessage;
use prost_reflect::{FileDescriptor, ReflectMessage};
use rustecal_core::types::DataTypeInfo;
use rustecal_pubsub::typed_publisher::PublisherMessage;
use rustecal_pubsub::typed_subscriber::SubscriberMessage;
Expand Down Expand Up @@ -34,14 +34,49 @@ where
/// This includes:
/// - `proto` as encoding
/// - the Rust type name
/// - an optional descriptor (currently empty)
/// - an optional descriptor
fn datatype() -> DataTypeInfo {
let default_instance = T::default();
let instance_descriptor = default_instance.descriptor();
let type_name = instance_descriptor.full_name().to_string();

let mut descriptor_pool = prost_reflect::DescriptorPool::new();

// List of proto files for a specific protobuf message type
let mut proto_filenames = instance_descriptor
.parent_file_descriptor_proto()
.dependency
.clone();
// Add the main proto message file
proto_filenames.push(
instance_descriptor
.parent_file_descriptor_proto()
.name()
.to_string(),
);

// Filter the pool to the set of file decriptors needed
Copy link

Copilot AI Aug 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a typo in the comment: 'decriptors' should be 'descriptors'.

Suggested change
// Filter the pool to the set of file decriptors needed
// Filter the pool to the set of file descriptors needed

Copilot uses AI. Check for mistakes.
let file_descriptors: Vec<FileDescriptor> = instance_descriptor
.parent_pool()
.files()
.filter(|s| proto_filenames.contains(&s.name().to_string()))
.collect();

for proto_file in file_descriptors.iter() {
let mut file_descriptor_proto = proto_file.file_descriptor_proto().clone();
// Remove the source_code_info from the descriptor which add excess comments
// from original proto to the descriptor message that aren't needed
file_descriptor_proto.source_code_info = None;

descriptor_pool
.add_file_descriptor_proto(file_descriptor_proto)
.unwrap();
Comment on lines +71 to +73
Copy link

Copilot AI Aug 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using unwrap() here could cause a panic if adding the file descriptor fails. Consider handling this error more gracefully or at least documenting when this could fail.

Copilot uses AI. Check for mistakes.
}

DataTypeInfo {
encoding: "proto".to_string(),
type_name: default_instance.descriptor().full_name().to_string(),
descriptor: default_instance.descriptor().parent_pool().encode_to_vec(), // descriptor injection planned
type_name,
descriptor: descriptor_pool.encode_to_vec(),
}
}

Expand All @@ -61,15 +96,17 @@ impl<T> PublisherMessage for ProtobufMessage<T>
where
T: Message + Default + IsProtobufType + ReflectMessage,
{
/// Returns the same datatype information as [`SubscriberMessage`] implementation.
/// Returns the same datatype information as [`SubscriberMessage`]
/// implementation.
fn datatype() -> DataTypeInfo {
<ProtobufMessage<T> as SubscriberMessage>::datatype()
}

/// Encodes the message to a byte buffer.
///
/// # Panics
/// Will panic if `prost::Message::encode` fails (should never panic for valid messages).
/// Will panic if `prost::Message::encode` fails (should never panic for
/// valid messages).
fn to_bytes(&self) -> Arc<[u8]> {
let mut buf = Vec::with_capacity(self.data.encoded_len());
self.data
Expand Down