33//! Provides support for Protobuf message serialization with rustecal.
44
55use prost:: Message ;
6- use prost_reflect:: ReflectMessage ;
6+ use prost_reflect:: { FileDescriptor , ReflectMessage } ;
77use rustecal_core:: types:: DataTypeInfo ;
88use rustecal_pubsub:: typed_publisher:: PublisherMessage ;
99use rustecal_pubsub:: typed_subscriber:: SubscriberMessage ;
@@ -34,14 +34,49 @@ where
3434 /// This includes:
3535 /// - `proto` as encoding
3636 /// - the Rust type name
37- /// - an optional descriptor (currently empty)
37+ /// - an optional descriptor
3838 fn datatype ( ) -> DataTypeInfo {
3939 let default_instance = T :: default ( ) ;
40+ let instance_descriptor = default_instance. descriptor ( ) ;
41+ let type_name = instance_descriptor. full_name ( ) . to_string ( ) ;
42+
43+ let mut descriptor_pool = prost_reflect:: DescriptorPool :: new ( ) ;
44+
45+ // List of proto files for a specific protobuf message type
46+ let mut proto_filenames = instance_descriptor
47+ . parent_file_descriptor_proto ( )
48+ . dependency
49+ . clone ( ) ;
50+ // Add the main proto message file
51+ proto_filenames. push (
52+ instance_descriptor
53+ . parent_file_descriptor_proto ( )
54+ . name ( )
55+ . to_string ( ) ,
56+ ) ;
57+
58+ // Filter the pool to the set of file decriptors needed
59+ let file_descriptors: Vec < FileDescriptor > = instance_descriptor
60+ . parent_pool ( )
61+ . files ( )
62+ . filter ( |s| proto_filenames. contains ( & s. name ( ) . to_string ( ) ) )
63+ . collect ( ) ;
64+
65+ for proto_file in file_descriptors. iter ( ) {
66+ let mut file_descriptor_proto = proto_file. file_descriptor_proto ( ) . clone ( ) ;
67+ // Remove the source_code_info from the descriptor which add excess comments
68+ // from original proto to the descriptor message that aren't needed
69+ file_descriptor_proto. source_code_info = None ;
70+
71+ descriptor_pool
72+ . add_file_descriptor_proto ( file_descriptor_proto)
73+ . unwrap ( ) ;
74+ }
4075
4176 DataTypeInfo {
4277 encoding : "proto" . to_string ( ) ,
43- type_name : default_instance . descriptor ( ) . full_name ( ) . to_string ( ) ,
44- descriptor : default_instance . descriptor ( ) . parent_pool ( ) . encode_to_vec ( ) , // descriptor injection planned
78+ type_name,
79+ descriptor : descriptor_pool . encode_to_vec ( ) ,
4580 }
4681 }
4782
@@ -61,15 +96,17 @@ impl<T> PublisherMessage for ProtobufMessage<T>
6196where
6297 T : Message + Default + IsProtobufType + ReflectMessage ,
6398{
64- /// Returns the same datatype information as [`SubscriberMessage`] implementation.
99+ /// Returns the same datatype information as [`SubscriberMessage`]
100+ /// implementation.
65101 fn datatype ( ) -> DataTypeInfo {
66102 <ProtobufMessage < T > as SubscriberMessage >:: datatype ( )
67103 }
68104
69105 /// Encodes the message to a byte buffer.
70106 ///
71107 /// # Panics
72- /// Will panic if `prost::Message::encode` fails (should never panic for valid messages).
108+ /// Will panic if `prost::Message::encode` fails (should never panic for
109+ /// valid messages).
73110 fn to_bytes ( & self ) -> Arc < [ u8 ] > {
74111 let mut buf = Vec :: with_capacity ( self . data . encoded_len ( ) ) ;
75112 self . data
0 commit comments