@@ -71,6 +71,42 @@ pub enum Ros2ReflectionError {
71
71
Downcast ( & ' static str ) ,
72
72
}
73
73
74
+ /// Minimal wrapper around [`StructBuilder`] that also holds the [`MessageSpecification`]
75
+ struct MessageStructBuilder {
76
+ builder : StructBuilder ,
77
+ spec : Arc < MessageSpecification > ,
78
+ }
79
+
80
+ impl ArrayBuilder for MessageStructBuilder {
81
+ fn as_any ( & self ) -> & dyn std:: any:: Any {
82
+ self
83
+ }
84
+
85
+ fn as_any_mut ( & mut self ) -> & mut dyn std:: any:: Any {
86
+ self
87
+ }
88
+
89
+ fn into_box_any ( self : Box < Self > ) -> Box < dyn std:: any:: Any > {
90
+ self
91
+ }
92
+
93
+ fn len ( & self ) -> usize {
94
+ self . builder . len ( )
95
+ }
96
+
97
+ fn is_empty ( & self ) -> bool {
98
+ self . builder . is_empty ( )
99
+ }
100
+
101
+ fn finish ( & mut self ) -> arrow:: array:: ArrayRef {
102
+ Arc :: new ( self . builder . finish ( ) )
103
+ }
104
+
105
+ fn finish_cloned ( & self ) -> arrow:: array:: ArrayRef {
106
+ Arc :: new ( self . builder . finish_cloned ( ) )
107
+ }
108
+ }
109
+
74
110
impl Ros2ReflectionMessageParser {
75
111
fn new ( num_rows : usize , message_schema : MessageSchema ) -> anyhow:: Result < Self > {
76
112
let mut fields = Vec :: new ( ) ;
@@ -110,7 +146,7 @@ impl MessageParser for Ros2ReflectionMessageParser {
110
146
// a field is missing from the message that we received.
111
147
for ( field_name, builder) in & mut self . fields {
112
148
if let Some ( field_value) = message_fields. get ( field_name) {
113
- append_value ( builder. values ( ) , field_value, & self . message_schema ) ?;
149
+ append_value ( builder. values ( ) , field_value) ?;
114
150
builder. append ( true ) ;
115
151
} else {
116
152
builder. append ( false ) ;
@@ -253,7 +289,6 @@ fn append_primitive_array(
253
289
fn append_value (
254
290
builder : & mut dyn ArrayBuilder ,
255
291
val : & Value ,
256
- schema : & MessageSchema ,
257
292
) -> Result < ( ) , Ros2ReflectionError > {
258
293
match val {
259
294
Value :: Bool ( x) => downcast_builder :: < BooleanBuilder > ( builder) ?. append_value ( * x) ,
@@ -271,41 +306,31 @@ fn append_value(
271
306
downcast_builder :: < StringBuilder > ( builder) ?. append_value ( x. clone ( ) ) ;
272
307
}
273
308
Value :: Message ( message_fields) => {
274
- let struct_builder = downcast_builder :: < StructBuilder > ( builder) ?;
275
-
276
- // For nested messages, we need to find the matching specification from dependencies
277
- // Since we don't have type information here, we'll try to match by field names
278
- let matching_spec = find_matching_message_spec ( schema, message_fields) ;
279
-
280
- if let Some ( spec) = matching_spec {
281
- // Use the specification field order to iterate through struct builder fields
282
- for ( i, spec_field) in spec. fields . iter ( ) . enumerate ( ) {
283
- if let Some ( field_builder) = struct_builder. field_builders_mut ( ) . get_mut ( i) {
284
- if let Some ( field_value) = message_fields. get ( & spec_field. name ) {
285
- append_value ( field_builder, field_value, schema) ?;
286
- } else {
287
- //TODO(gijsd): Field is missing in the message, append null
288
- re_log:: warn_once!(
289
- "Field {} is missing in the message, appending null" ,
290
- spec_field. name
291
- ) ;
292
- }
309
+ let message_struct_builder = downcast_builder :: < MessageStructBuilder > ( builder) ?;
310
+ let spec = & message_struct_builder. spec ;
311
+
312
+ // Use the specification field order to iterate through struct builder fields
313
+ for ( i, spec_field) in spec. fields . iter ( ) . enumerate ( ) {
314
+ if let Some ( field_builder) = message_struct_builder. builder . field_builders_mut ( ) . get_mut ( i) {
315
+ if let Some ( field_value) = message_fields. get ( & spec_field. name ) {
316
+ append_value ( field_builder, field_value) ?;
317
+ } else {
318
+ //TODO(gijsd): Field is missing in the message, append null
319
+ re_log:: warn_once!(
320
+ "Field {} is missing in the message, appending null" ,
321
+ spec_field. name
322
+ ) ;
293
323
}
294
324
}
295
- } else {
296
- re_log:: warn_once!(
297
- "Could not find matching message specification for nested message with fields: {:?}" ,
298
- message_fields. keys( ) . collect:: <Vec <_>>( )
299
- ) ;
300
325
}
301
326
302
- struct_builder . append ( true ) ;
327
+ message_struct_builder . builder . append ( true ) ;
303
328
}
304
329
Value :: Array ( vec) | Value :: Sequence ( vec) => {
305
330
let list_builder = downcast_builder :: < ListBuilder < Box < dyn ArrayBuilder > > > ( builder) ?;
306
331
307
332
for val in vec {
308
- append_value ( list_builder. values ( ) , val, schema ) ?;
333
+ append_value ( list_builder. values ( ) , val) ?;
309
334
}
310
335
list_builder. append ( true ) ;
311
336
}
@@ -317,23 +342,10 @@ fn append_value(
317
342
Ok ( ( ) )
318
343
}
319
344
320
- fn find_matching_message_spec < ' a > (
321
- schema : & ' a MessageSchema ,
322
- message_fields : & ' a std:: collections:: BTreeMap < String , Value > ,
323
- ) -> Option < & ' a MessageSpecification > {
324
- schema. dependencies . iter ( ) . find ( |spec| {
325
- spec. fields . len ( ) == message_fields. len ( )
326
- && spec
327
- . fields
328
- . iter ( )
329
- . all ( |f| message_fields. contains_key ( & f. name ) )
330
- } )
331
- }
332
-
333
345
fn struct_builder_from_message_spec (
334
346
spec : & MessageSpecification ,
335
347
dependencies : & [ MessageSpecification ] ,
336
- ) -> anyhow:: Result < StructBuilder > {
348
+ ) -> anyhow:: Result < MessageStructBuilder > {
337
349
let fields = spec
338
350
. fields
339
351
. iter ( )
@@ -348,7 +360,10 @@ fn struct_builder_from_message_spec(
348
360
let ( fields, field_builders) : ( Vec < Field > , Vec < Box < dyn ArrayBuilder > > ) =
349
361
fields. into_iter ( ) . unzip ( ) ;
350
362
351
- Ok ( StructBuilder :: new ( fields, field_builders) )
363
+ Ok ( MessageStructBuilder {
364
+ builder : StructBuilder :: new ( fields, field_builders) ,
365
+ spec : Arc :: new ( spec. clone ( ) ) ,
366
+ } )
352
367
}
353
368
354
369
fn arrow_builder_from_type (
0 commit comments