@@ -16,7 +16,7 @@ use crate::{
16
16
should_optimize_buffer_slice_deserialize,
17
17
} ,
18
18
serializer:: quote_arrow_serializer,
19
- util:: { is_tuple_struct_from_obj, iter_archetype_components , quote_doc_line} ,
19
+ util:: { is_tuple_struct_from_obj, quote_doc_line} ,
20
20
} ,
21
21
Target ,
22
22
} ,
@@ -184,7 +184,7 @@ fn generate_object_file(
184
184
code. push_str ( "use ::re_types_core::external::arrow2;\n " ) ;
185
185
code. push_str ( "use ::re_types_core::SerializationResult;\n " ) ;
186
186
code. push_str ( "use ::re_types_core::{DeserializationResult, DeserializationError};\n " ) ;
187
- code. push_str ( "use ::re_types_core::ComponentName;\n " ) ;
187
+ code. push_str ( "use ::re_types_core::{ComponentDescriptor, ComponentName} ;\n " ) ;
188
188
code. push_str ( "use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch};\n " ) ;
189
189
190
190
// NOTE: `TokenStream`s discard whitespacing information by definition, so we need to
@@ -354,13 +354,13 @@ fn quote_struct(
354
354
#quoted_deprecation_notice
355
355
#quoted_struct
356
356
357
- #quoted_heap_size_bytes
357
+ #quoted_trait_impls
358
358
359
359
#quoted_from_impl
360
360
361
- #quoted_trait_impls
362
-
363
361
#quoted_builder
362
+
363
+ #quoted_heap_size_bytes
364
364
} ;
365
365
366
366
tokens
@@ -470,9 +470,9 @@ fn quote_union(
470
470
#( #quoted_fields, ) *
471
471
}
472
472
473
- #quoted_heap_size_bytes
474
-
475
473
#quoted_trait_impls
474
+
475
+ #quoted_heap_size_bytes
476
476
} ;
477
477
478
478
tokens
@@ -603,6 +603,18 @@ fn quote_enum(
603
603
#( #quoted_fields, ) *
604
604
}
605
605
606
+ #quoted_trait_impls
607
+
608
+ // We implement `Display` to match the `PascalCase` name so that
609
+ // the enum variants are displayed in the UI exactly how they are displayed in code.
610
+ impl std:: fmt:: Display for #name {
611
+ fn fmt( & self , f: & mut std:: fmt:: Formatter <' _>) -> std:: fmt:: Result {
612
+ match self {
613
+ #( #display_match_arms, ) *
614
+ }
615
+ }
616
+ }
617
+
606
618
impl :: re_types_core:: reflection:: Enum for #name {
607
619
608
620
#[ inline]
@@ -629,18 +641,6 @@ fn quote_enum(
629
641
true
630
642
}
631
643
}
632
-
633
- // We implement `Display` to match the `PascalCase` name so that
634
- // the enum variants are displayed in the UI exactly how they are displayed in code.
635
- impl std:: fmt:: Display for #name {
636
- fn fmt( & self , f: & mut std:: fmt:: Formatter <' _>) -> std:: fmt:: Result {
637
- match self {
638
- #( #display_match_arms, ) *
639
- }
640
- }
641
- }
642
-
643
- #quoted_trait_impls
644
644
} ;
645
645
646
646
tokens
@@ -1006,14 +1006,16 @@ fn quote_trait_impls_for_datatype_or_component(
1006
1006
quote ! {
1007
1007
impl :: re_types_core:: Component for #name {
1008
1008
#[ inline]
1009
- fn name ( ) -> ComponentName {
1010
- #fqname. into ( )
1009
+ fn descriptor ( ) -> ComponentDescriptor {
1010
+ ComponentDescriptor :: new ( #fqname)
1011
1011
}
1012
1012
}
1013
1013
}
1014
1014
} ) ;
1015
1015
1016
1016
quote ! {
1017
+ #quoted_impl_component
1018
+
1017
1019
:: re_types_core:: macros:: impl_into_cow!( #name) ;
1018
1020
1019
1021
impl :: re_types_core:: Loggable for #name {
@@ -1033,8 +1035,6 @@ fn quote_trait_impls_for_datatype_or_component(
1033
1035
1034
1036
#quoted_from_arrow2
1035
1037
}
1036
-
1037
- #quoted_impl_component
1038
1038
}
1039
1039
}
1040
1040
@@ -1048,40 +1048,70 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream {
1048
1048
assert_eq ! ( kind, & ObjectKind :: Archetype ) ;
1049
1049
1050
1050
let display_name = re_case:: to_human_case ( name) ;
1051
+ let archetype_name = & obj. fqname ;
1051
1052
let name = format_ident ! ( "{name}" ) ;
1052
1053
1053
- fn compute_components (
1054
+ fn compute_component_descriptors (
1054
1055
obj : & Object ,
1055
- attr : & ' static str ,
1056
- extras : impl IntoIterator < Item = String > ,
1056
+ requirement_attr_value : & ' static str ,
1057
1057
) -> ( usize , TokenStream ) {
1058
- let components = iter_archetype_components ( obj, attr)
1059
- . chain ( extras)
1060
- // Do *not* sort again, we want to preserve the order given by the datatype definition
1061
- . collect :: < Vec < _ > > ( ) ;
1058
+ let descriptors = obj
1059
+ . fields
1060
+ . iter ( )
1061
+ . filter_map ( move |field| {
1062
+ field
1063
+ . try_get_attr :: < String > ( requirement_attr_value)
1064
+ . map ( |_| {
1065
+ let Some ( component_name) = field. typ . fqname ( ) else {
1066
+ panic ! ( "Archetype field must be an object/union or an array/vector of such" )
1067
+ } ;
1068
+
1069
+ let archetype_name = & obj. fqname ;
1070
+ let archetype_field_name = field. snake_case_name ( ) ;
1071
+
1072
+ quote ! ( ComponentDescriptor {
1073
+ archetype_name: Some ( #archetype_name. into( ) ) ,
1074
+ component_name: #component_name. into( ) ,
1075
+ archetype_field_name: Some ( #archetype_field_name. into( ) ) ,
1076
+ } )
1077
+ } )
1078
+ } )
1079
+ . collect_vec ( ) ;
1062
1080
1063
- let num_components = components . len ( ) ;
1064
- let quoted_components = quote ! ( #( #components . into ( ) , ) * ) ;
1081
+ let num_descriptors = descriptors . len ( ) ;
1082
+ let quoted_descriptors = quote ! ( #( #descriptors , ) * ) ;
1065
1083
1066
- ( num_components , quoted_components )
1084
+ ( num_descriptors , quoted_descriptors )
1067
1085
}
1068
1086
1069
1087
let indicator_name = format ! ( "{}Indicator" , obj. name) ;
1070
- let indicator_fqname = format ! ( "{}Indicator" , obj. fqname) . replace ( "archetypes" , "components" ) ;
1071
1088
1072
1089
let quoted_indicator_name = format_ident ! ( "{indicator_name}" ) ;
1073
1090
let quoted_indicator_doc =
1074
1091
format ! ( "Indicator component for the [`{name}`] [`::re_types_core::Archetype`]" ) ;
1075
1092
1076
- let ( num_required, required) = compute_components ( obj, ATTR_RERUN_COMPONENT_REQUIRED , [ ] ) ;
1077
- let ( num_recommended, recommended) =
1078
- compute_components ( obj, ATTR_RERUN_COMPONENT_RECOMMENDED , [ indicator_fqname] ) ;
1079
- let ( num_optional, optional) = compute_components ( obj, ATTR_RERUN_COMPONENT_OPTIONAL , [ ] ) ;
1093
+ let ( num_required_descriptors, required_descriptors) =
1094
+ compute_component_descriptors ( obj, ATTR_RERUN_COMPONENT_REQUIRED ) ;
1095
+ let ( mut num_recommended_descriptors, mut recommended_descriptors) =
1096
+ compute_component_descriptors ( obj, ATTR_RERUN_COMPONENT_RECOMMENDED ) ;
1097
+ let ( num_optional_descriptors, optional_descriptors) =
1098
+ compute_component_descriptors ( obj, ATTR_RERUN_COMPONENT_OPTIONAL ) ;
1099
+
1100
+ num_recommended_descriptors += 1 ;
1101
+ recommended_descriptors = quote ! {
1102
+ #recommended_descriptors
1103
+ ComponentDescriptor {
1104
+ archetype_name: Some ( #archetype_name. into( ) ) ,
1105
+ component_name: #indicator_name. into( ) ,
1106
+ archetype_field_name: None ,
1107
+ } ,
1108
+ } ;
1080
1109
1081
1110
let num_components_docstring = quote_doc_line ( & format ! (
1082
- "The total number of components in the archetype: {num_required } required, {num_recommended } recommended, {num_optional } optional"
1111
+ "The total number of components in the archetype: {num_required_descriptors } required, {num_recommended_descriptors } recommended, {num_optional_descriptors } optional"
1083
1112
) ) ;
1084
- let num_all = num_required + num_recommended + num_optional;
1113
+ let num_all_descriptors =
1114
+ num_required_descriptors + num_recommended_descriptors + num_optional_descriptors;
1085
1115
1086
1116
let quoted_field_names = obj
1087
1117
. fields
@@ -1099,13 +1129,13 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream {
1099
1129
1100
1130
// NOTE: The nullability we're dealing with here is the nullability of an entire array of components,
1101
1131
// not the nullability of individual elements (i.e. instances)!
1102
- if is_nullable {
1132
+ let batch = if is_nullable {
1103
1133
if obj. attrs . has ( ATTR_RERUN_LOG_MISSING_AS_EMPTY ) {
1104
1134
if is_plural {
1105
1135
// Always log Option<Vec<C>> as Vec<V>, mapping None to empty batch
1106
1136
let component_type = quote_field_type_from_typ ( & obj_field. typ , false ) . 0 ;
1107
1137
quote ! {
1108
- Some ( (
1138
+ Some (
1109
1139
if let Some ( comp_batch) = & self . #field_name {
1110
1140
( comp_batch as & dyn ComponentBatch )
1111
1141
} else {
@@ -1114,24 +1144,44 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream {
1114
1144
let empty_batch: & #component_type = EMPTY_BATCH . get_or_init( || Vec :: new( ) ) ;
1115
1145
( empty_batch as & dyn ComponentBatch )
1116
1146
}
1117
- ) . into ( ) )
1147
+ )
1118
1148
}
1119
1149
} else {
1120
1150
// Always log Option<C>, mapping None to empty batch
1121
- quote ! { Some ( ( & self . #field_name as & dyn ComponentBatch ) . into ( ) ) }
1151
+ quote ! { Some ( & self . #field_name as & dyn ComponentBatch ) }
1122
1152
}
1123
1153
} else {
1124
1154
if is_plural {
1125
1155
// Maybe logging an Option<Vec<C>>
1126
- quote ! { self . #field_name. as_ref( ) . map( |comp_batch| ( comp_batch as & dyn ComponentBatch ) . into ( ) ) }
1156
+ quote ! { self . #field_name. as_ref( ) . map( |comp_batch| ( comp_batch as & dyn ComponentBatch ) ) }
1127
1157
} else {
1128
1158
// Maybe logging an Option<C>
1129
- quote ! { self . #field_name. as_ref( ) . map( |comp| ( comp as & dyn ComponentBatch ) . into ( ) ) }
1159
+ quote ! { self . #field_name. as_ref( ) . map( |comp| ( comp as & dyn ComponentBatch ) ) }
1130
1160
}
1131
1161
}
1132
1162
} else {
1133
1163
// Always logging a Vec<C> or C
1134
- quote ! { Some ( ( & self . #field_name as & dyn ComponentBatch ) . into( ) ) }
1164
+ quote ! { Some ( & self . #field_name as & dyn ComponentBatch ) }
1165
+ } ;
1166
+
1167
+ let Some ( component_name) = obj_field. typ . fqname ( ) else {
1168
+ panic ! ( "Archetype field must be an object/union or an array/vector of such" )
1169
+ } ;
1170
+ let archetype_name = & obj. fqname ;
1171
+ let archetype_field_name = obj_field. snake_case_name ( ) ;
1172
+
1173
+ quote ! {
1174
+ ( #batch) . map( |batch| {
1175
+ :: re_types_core:: MaybeOwnedComponentBatch {
1176
+ batch: batch. into( ) ,
1177
+ descriptor_override: Some ( ComponentDescriptor {
1178
+ archetype_name: Some ( #archetype_name. into( ) ) ,
1179
+ archetype_field_name: Some ( ( #archetype_field_name) . into( ) ) ,
1180
+ component_name: ( #component_name) . into( ) ,
1181
+ } ) ,
1182
+ }
1183
+ } )
1184
+
1135
1185
}
1136
1186
} ) )
1137
1187
} ;
@@ -1215,21 +1265,21 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream {
1215
1265
} ;
1216
1266
1217
1267
quote ! {
1218
- static REQUIRED_COMPONENTS : once_cell:: sync:: Lazy <[ ComponentName ; #num_required ] > =
1219
- once_cell:: sync:: Lazy :: new( || { [ #required ] } ) ;
1268
+ static REQUIRED_COMPONENTS : once_cell:: sync:: Lazy <[ ComponentDescriptor ; #num_required_descriptors ] > =
1269
+ once_cell:: sync:: Lazy :: new( || { [ #required_descriptors ] } ) ;
1220
1270
1221
- static RECOMMENDED_COMPONENTS : once_cell:: sync:: Lazy <[ ComponentName ; #num_recommended ] > =
1222
- once_cell:: sync:: Lazy :: new( || { [ #recommended ] } ) ;
1271
+ static RECOMMENDED_COMPONENTS : once_cell:: sync:: Lazy <[ ComponentDescriptor ; #num_recommended_descriptors ] > =
1272
+ once_cell:: sync:: Lazy :: new( || { [ #recommended_descriptors ] } ) ;
1223
1273
1224
- static OPTIONAL_COMPONENTS : once_cell:: sync:: Lazy <[ ComponentName ; #num_optional ] > =
1225
- once_cell:: sync:: Lazy :: new( || { [ #optional ] } ) ;
1274
+ static OPTIONAL_COMPONENTS : once_cell:: sync:: Lazy <[ ComponentDescriptor ; #num_optional_descriptors ] > =
1275
+ once_cell:: sync:: Lazy :: new( || { [ #optional_descriptors ] } ) ;
1226
1276
1227
- static ALL_COMPONENTS : once_cell:: sync:: Lazy <[ ComponentName ; #num_all ] > =
1228
- once_cell:: sync:: Lazy :: new( || { [ #required #recommended #optional ] } ) ;
1277
+ static ALL_COMPONENTS : once_cell:: sync:: Lazy <[ ComponentDescriptor ; #num_all_descriptors ] > =
1278
+ once_cell:: sync:: Lazy :: new( || { [ #required_descriptors #recommended_descriptors #optional_descriptors ] } ) ;
1229
1279
1230
1280
impl #name {
1231
1281
#num_components_docstring
1232
- pub const NUM_COMPONENTS : usize = #num_all ;
1282
+ pub const NUM_COMPONENTS : usize = #num_all_descriptors ;
1233
1283
}
1234
1284
1235
1285
#[ doc = #quoted_indicator_doc]
@@ -1251,27 +1301,27 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream {
1251
1301
#[ inline]
1252
1302
fn indicator( ) -> MaybeOwnedComponentBatch <' static > {
1253
1303
static INDICATOR : #quoted_indicator_name = #quoted_indicator_name:: DEFAULT ;
1254
- MaybeOwnedComponentBatch :: Ref ( & INDICATOR )
1304
+ MaybeOwnedComponentBatch :: new ( & INDICATOR as & dyn :: re_types_core :: ComponentBatch )
1255
1305
}
1256
1306
1257
1307
#[ inline]
1258
- fn required_components( ) -> :: std:: borrow:: Cow <' static , [ ComponentName ] > {
1308
+ fn required_components( ) -> :: std:: borrow:: Cow <' static , [ ComponentDescriptor ] > {
1259
1309
REQUIRED_COMPONENTS . as_slice( ) . into( )
1260
1310
}
1261
1311
1262
1312
#[ inline]
1263
- fn recommended_components( ) -> :: std:: borrow:: Cow <' static , [ ComponentName ] > {
1313
+ fn recommended_components( ) -> :: std:: borrow:: Cow <' static , [ ComponentDescriptor ] > {
1264
1314
RECOMMENDED_COMPONENTS . as_slice( ) . into( )
1265
1315
}
1266
1316
1267
1317
#[ inline]
1268
- fn optional_components( ) -> :: std:: borrow:: Cow <' static , [ ComponentName ] > {
1318
+ fn optional_components( ) -> :: std:: borrow:: Cow <' static , [ ComponentDescriptor ] > {
1269
1319
OPTIONAL_COMPONENTS . as_slice( ) . into( )
1270
1320
}
1271
1321
1272
1322
// NOTE: Don't rely on default implementation so that we can keep everything static.
1273
1323
#[ inline]
1274
- fn all_components( ) -> :: std:: borrow:: Cow <' static , [ ComponentName ] > {
1324
+ fn all_components( ) -> :: std:: borrow:: Cow <' static , [ ComponentDescriptor ] > {
1275
1325
ALL_COMPONENTS . as_slice( ) . into( )
1276
1326
}
1277
1327
@@ -1306,7 +1356,6 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream {
1306
1356
re_tracing:: profile_function!( ) ;
1307
1357
1308
1358
use :: re_types_core:: Archetype as _;
1309
-
1310
1359
[ #( #all_component_batches, ) * ] . into_iter( ) . flatten( ) . collect( )
1311
1360
}
1312
1361
}
0 commit comments