@@ -136,19 +136,19 @@ impl Field {
136
136
Type :: Option ( _) => unimplemented ! ( "Unsupported nesting encountered" ) ,
137
137
Type :: Reference ( _, ref second_type)
138
138
| Type :: Vec ( ref second_type)
139
- | Type :: Array ( ref second_type)
139
+ | Type :: Array ( ref second_type, _ )
140
140
| Type :: Slice ( ref second_type) => match * * second_type {
141
141
Type :: TypePath ( _) => Some ( self . optional_definition_levels ( ) ) ,
142
142
_ => unimplemented ! ( "Unsupported nesting encountered" ) ,
143
143
} ,
144
144
} ,
145
145
Type :: Reference ( _, ref first_type)
146
146
| Type :: Vec ( ref first_type)
147
- | Type :: Array ( ref first_type)
147
+ | Type :: Array ( ref first_type, _ )
148
148
| Type :: Slice ( ref first_type) => match * * first_type {
149
149
Type :: TypePath ( _) => None ,
150
150
Type :: Vec ( ref second_type)
151
- | Type :: Array ( ref second_type)
151
+ | Type :: Array ( ref second_type, _ )
152
152
| Type :: Slice ( ref second_type) => match * * second_type {
153
153
Type :: TypePath ( _) => None ,
154
154
Type :: Reference ( _, ref third_type) => match * * third_type {
@@ -161,7 +161,7 @@ impl Field {
161
161
match * * second_type {
162
162
Type :: TypePath ( _) => Some ( self . optional_definition_levels ( ) ) ,
163
163
Type :: Vec ( ref third_type)
164
- | Type :: Array ( ref third_type)
164
+ | Type :: Array ( ref third_type, _ )
165
165
| Type :: Slice ( ref third_type) => match * * third_type {
166
166
Type :: TypePath ( _) => Some ( self . optional_definition_levels ( ) ) ,
167
167
Type :: Reference ( _, ref fourth_type) => match * * fourth_type {
@@ -316,25 +316,23 @@ impl Field {
316
316
let logical_type = self . ty . logical_type ( ) ;
317
317
let repetition = self . ty . repetition ( ) ;
318
318
let converted_type = self . ty . converted_type ( ) ;
319
+ let length = self . ty . length ( ) ;
320
+
321
+ let mut builder = quote ! {
322
+ ParquetType :: primitive_type_builder( #field_name, #physical_type)
323
+ . with_logical_type( #logical_type)
324
+ . with_repetition( #repetition)
325
+ } ;
319
326
320
327
if let Some ( converted_type) = converted_type {
321
- quote ! {
322
- fields. push( ParquetType :: primitive_type_builder( #field_name, #physical_type)
323
- . with_logical_type( #logical_type)
324
- . with_repetition( #repetition)
325
- . with_converted_type( #converted_type)
326
- . build( ) . unwrap( ) . into( )
327
- )
328
- }
329
- } else {
330
- quote ! {
331
- fields. push( ParquetType :: primitive_type_builder( #field_name, #physical_type)
332
- . with_logical_type( #logical_type)
333
- . with_repetition( #repetition)
334
- . build( ) . unwrap( ) . into( )
335
- )
336
- }
328
+ builder = quote ! { #builder. with_converted_type( #converted_type) } ;
329
+ }
330
+
331
+ if let Some ( length) = length {
332
+ builder = quote ! { #builder. with_length( #length) } ;
337
333
}
334
+
335
+ quote ! { fields. push( #builder. build( ) . unwrap( ) . into( ) ) }
338
336
}
339
337
340
338
fn option_into_vals ( & self ) -> proc_macro2:: TokenStream {
@@ -394,7 +392,7 @@ impl Field {
394
392
quote ! { rec. #field_name. signed_duration_since( :: chrono:: NaiveDate :: from_ymd( 1970 , 1 , 1 ) ) . num_days( ) as i32 }
395
393
}
396
394
Some ( ThirdPartyType :: Uuid ) => {
397
- quote ! { ( & rec. #field_name. to_string ( ) [ .. ] ) . into( ) }
395
+ quote ! { rec. #field_name. as_bytes ( ) . to_vec ( ) . into( ) }
398
396
}
399
397
_ => {
400
398
if self . is_a_byte_buf {
@@ -430,7 +428,7 @@ impl Field {
430
428
}
431
429
}
432
430
Some ( ThirdPartyType :: Uuid ) => {
433
- quote ! { :: uuid:: Uuid :: parse_str ( vals[ i] . data( ) . convert ( ) ) . unwrap( ) }
431
+ quote ! { :: uuid:: Uuid :: from_bytes ( vals[ i] . data( ) . try_into ( ) . unwrap( ) ) }
434
432
}
435
433
_ => match & self . ty {
436
434
Type :: TypePath ( _) => match self . ty . last_part ( ) . as_str ( ) {
@@ -469,7 +467,7 @@ impl Field {
469
467
#[ allow( clippy:: large_enum_variant) ]
470
468
#[ derive( Debug , PartialEq ) ]
471
469
enum Type {
472
- Array ( Box < Type > ) ,
470
+ Array ( Box < Type > , syn :: Expr ) ,
473
471
Option ( Box < Type > ) ,
474
472
Slice ( Box < Type > ) ,
475
473
Vec ( Box < Type > ) ,
@@ -542,7 +540,7 @@ impl Type {
542
540
Type :: TypePath ( _) => parent_ty. unwrap_or ( ty) ,
543
541
Type :: Option ( ref first_type)
544
542
| Type :: Vec ( ref first_type)
545
- | Type :: Array ( ref first_type)
543
+ | Type :: Array ( ref first_type, _ )
546
544
| Type :: Slice ( ref first_type)
547
545
| Type :: Reference ( _, ref first_type) => {
548
546
Type :: leaf_type_recursive_helper ( first_type, Some ( ty) )
@@ -560,7 +558,7 @@ impl Type {
560
558
Type :: TypePath ( ref type_) => type_,
561
559
Type :: Option ( ref first_type)
562
560
| Type :: Vec ( ref first_type)
563
- | Type :: Array ( ref first_type)
561
+ | Type :: Array ( ref first_type, _ )
564
562
| Type :: Slice ( ref first_type)
565
563
| Type :: Reference ( _, ref first_type) => match * * first_type {
566
564
Type :: TypePath ( ref type_) => type_,
@@ -607,7 +605,7 @@ impl Type {
607
605
let leaf_type = self . leaf_type_recursive ( ) ;
608
606
609
607
match leaf_type {
610
- Type :: Array ( ref first_type) => {
608
+ Type :: Array ( ref first_type, _length ) => {
611
609
if let Type :: TypePath ( _) = * * first_type {
612
610
if last_part == "u8" {
613
611
return BasicType :: FIXED_LEN_BYTE_ARRAY ;
@@ -638,17 +636,38 @@ impl Type {
638
636
}
639
637
"f32" => BasicType :: FLOAT ,
640
638
"f64" => BasicType :: DOUBLE ,
641
- "String" | "str" | "Uuid" => BasicType :: BYTE_ARRAY ,
639
+ "String" | "str" => BasicType :: BYTE_ARRAY ,
640
+ "Uuid" => BasicType :: FIXED_LEN_BYTE_ARRAY ,
642
641
f => unimplemented ! ( "{} currently is not supported" , f) ,
643
642
}
644
643
}
645
644
645
+ fn length ( & self ) -> Option < syn:: Expr > {
646
+ let last_part = self . last_part ( ) ;
647
+ let leaf_type = self . leaf_type_recursive ( ) ;
648
+
649
+ // `[u8; N]` => Some(N)
650
+ if let Type :: Array ( ref first_type, length) = leaf_type {
651
+ if let Type :: TypePath ( _) = * * first_type {
652
+ if last_part == "u8" {
653
+ return Some ( length. clone ( ) ) ;
654
+ }
655
+ }
656
+ }
657
+
658
+ match last_part. trim ( ) {
659
+ // Uuid => [u8; 16] => Some(16)
660
+ "Uuid" => Some ( syn:: parse_quote!( 16 ) ) ,
661
+ _ => None ,
662
+ }
663
+ }
664
+
646
665
fn logical_type ( & self ) -> proc_macro2:: TokenStream {
647
666
let last_part = self . last_part ( ) ;
648
667
let leaf_type = self . leaf_type_recursive ( ) ;
649
668
650
669
match leaf_type {
651
- Type :: Array ( ref first_type) => {
670
+ Type :: Array ( ref first_type, _length ) => {
652
671
if let Type :: TypePath ( _) = * * first_type {
653
672
if last_part == "u8" {
654
673
return quote ! { None } ;
@@ -789,7 +808,7 @@ impl Type {
789
808
790
809
fn from_type_array ( f : & syn:: Field , ta : & syn:: TypeArray ) -> Self {
791
810
let inner_type = Type :: from_type ( f, ta. elem . as_ref ( ) ) ;
792
- Type :: Array ( Box :: new ( inner_type) )
811
+ Type :: Array ( Box :: new ( inner_type) , ta . len . clone ( ) )
793
812
}
794
813
795
814
fn from_type_slice ( f : & syn:: Field , ts : & syn:: TypeSlice ) -> Self {
@@ -1091,6 +1110,7 @@ mod test {
1091
1110
a_fix_byte_buf: [ u8 ; 10 ] ,
1092
1111
a_complex_option: :: std:: option:: Option <& Vec <u8 >>,
1093
1112
a_complex_vec: & :: std:: vec:: Vec <& Option <u8 >>,
1113
+ a_uuid: :: uuid:: Uuid ,
1094
1114
}
1095
1115
} ;
1096
1116
@@ -1110,7 +1130,42 @@ mod test {
1110
1130
BasicType :: BYTE_ARRAY ,
1111
1131
BasicType :: FIXED_LEN_BYTE_ARRAY ,
1112
1132
BasicType :: BYTE_ARRAY ,
1113
- BasicType :: INT32
1133
+ BasicType :: INT32 ,
1134
+ BasicType :: FIXED_LEN_BYTE_ARRAY ,
1135
+ ]
1136
+ )
1137
+ }
1138
+
1139
+ #[ test]
1140
+ fn test_type_length ( ) {
1141
+ let snippet: proc_macro2:: TokenStream = quote ! {
1142
+ struct LotsOfInnerTypes {
1143
+ a_buf: :: std:: vec:: Vec <u8 >,
1144
+ a_number: i32 ,
1145
+ a_verbose_option: :: std:: option:: Option <bool >,
1146
+ a_silly_string: String ,
1147
+ a_fix_byte_buf: [ u8 ; 10 ] ,
1148
+ a_complex_option: :: std:: option:: Option <& Vec <u8 >>,
1149
+ a_complex_vec: & :: std:: vec:: Vec <& Option <u8 >>,
1150
+ a_uuid: :: uuid:: Uuid ,
1151
+ }
1152
+ } ;
1153
+
1154
+ let fields = extract_fields ( snippet) ;
1155
+ let converted_fields: Vec < _ > = fields. iter ( ) . map ( Type :: from) . collect ( ) ;
1156
+ let lengths: Vec < _ > = converted_fields. iter ( ) . map ( |ty| ty. length ( ) ) . collect ( ) ;
1157
+
1158
+ assert_eq ! (
1159
+ lengths,
1160
+ vec![
1161
+ None ,
1162
+ None ,
1163
+ None ,
1164
+ None ,
1165
+ Some ( syn:: parse_quote!( 10 ) ) ,
1166
+ None ,
1167
+ None ,
1168
+ Some ( syn:: parse_quote!( 16 ) ) ,
1114
1169
]
1115
1170
)
1116
1171
}
@@ -1328,8 +1383,8 @@ mod test {
1328
1383
let when = Field :: from ( & fields[ 0 ] ) ;
1329
1384
assert_eq ! ( when. writer_snippet( ) . to_string( ) , ( quote!{
1330
1385
{
1331
- let vals : Vec <_> = records. iter( ) . map( |rec| ( & rec. unique_id. to_string ( ) [ .. ] ) . into( ) ) . collect( ) ;
1332
- if let ColumnWriter :: ByteArrayColumnWriter ( ref mut typed) = column_writer. untyped( ) {
1386
+ let vals : Vec <_> = records. iter( ) . map( |rec| rec. unique_id. as_bytes ( ) . to_vec ( ) . into( ) ) . collect( ) ;
1387
+ if let ColumnWriter :: FixedLenByteArrayColumnWriter ( ref mut typed) = column_writer. untyped( ) {
1333
1388
typed. write_batch( & vals[ ..] , None , None ) ?;
1334
1389
} else {
1335
1390
panic!( "Schema and struct disagree on type for {}" , stringify!{ unique_id } )
@@ -1349,7 +1404,7 @@ mod test {
1349
1404
}
1350
1405
} ) . collect( ) ;
1351
1406
1352
- if let ColumnWriter :: ByteArrayColumnWriter ( ref mut typed) = column_writer. untyped( ) {
1407
+ if let ColumnWriter :: FixedLenByteArrayColumnWriter ( ref mut typed) = column_writer. untyped( ) {
1353
1408
typed. write_batch( & vals[ ..] , Some ( & definition_levels[ ..] ) , None ) ?;
1354
1409
} else {
1355
1410
panic!( "Schema and struct disagree on type for {}" , stringify!{ maybe_unique_id } )
@@ -1371,13 +1426,13 @@ mod test {
1371
1426
assert_eq ! ( when. reader_snippet( ) . to_string( ) , ( quote!{
1372
1427
{
1373
1428
let mut vals = Vec :: new( ) ;
1374
- if let ColumnReader :: ByteArrayColumnReader ( mut typed) = column_reader {
1429
+ if let ColumnReader :: FixedLenByteArrayColumnReader ( mut typed) = column_reader {
1375
1430
typed. read_records( num_records, None , None , & mut vals) ?;
1376
1431
} else {
1377
1432
panic!( "Schema and struct disagree on type for {}" , stringify!{ unique_id } ) ;
1378
1433
}
1379
1434
for ( i, r) in & mut records[ ..num_records] . iter_mut( ) . enumerate( ) {
1380
- r. unique_id = :: uuid:: Uuid :: parse_str ( vals[ i] . data( ) . convert ( ) ) . unwrap( ) ;
1435
+ r. unique_id = :: uuid:: Uuid :: from_bytes ( vals[ i] . data( ) . try_into ( ) . unwrap( ) ) ;
1381
1436
}
1382
1437
}
1383
1438
} ) . to_string( ) ) ;
0 commit comments