1
1
use itertools:: Itertools ;
2
+ use vortex_array:: aliases:: hash_set:: HashSet ;
2
3
use vortex_array:: iter:: ArrayIteratorArrayExt ;
3
4
use vortex_array:: { ArrayContext , ArrayRef } ;
4
5
use vortex_dtype:: DType ;
5
- use vortex_error:: { VortexExpect , VortexResult , vortex_bail, vortex_err, vortex_panic } ;
6
+ use vortex_error:: { VortexExpect , VortexResult , vortex_bail, vortex_err} ;
6
7
7
8
use crate :: LayoutVTableRef ;
8
9
use crate :: data:: Layout ;
@@ -19,33 +20,43 @@ pub struct StructLayoutWriter {
19
20
}
20
21
21
22
impl StructLayoutWriter {
22
- pub fn new ( dtype : DType , column_layout_writers : Vec < Box < dyn LayoutWriter > > ) -> Self {
23
- let struct_dtype = dtype. as_struct ( ) . vortex_expect ( "dtype is not a struct" ) ;
23
+ pub fn try_new (
24
+ dtype : DType ,
25
+ column_layout_writers : Vec < Box < dyn LayoutWriter > > ,
26
+ ) -> VortexResult < Self > {
27
+ let struct_dtype = dtype
28
+ . as_struct ( )
29
+ . ok_or_else ( || vortex_err ! ( "expected StructDType" ) ) ?;
30
+ if HashSet :: from_iter ( struct_dtype. names ( ) . iter ( ) ) . len ( ) != struct_dtype. names ( ) . len ( ) {
31
+ vortex_bail ! ( "StructLayout must have unique field names" )
32
+ }
24
33
if struct_dtype. fields ( ) . len ( ) != column_layout_writers. len ( ) {
25
- vortex_panic ! (
34
+ vortex_bail ! (
26
35
"number of fields in struct dtype does not match number of column layout writers"
27
36
) ;
28
37
}
29
- Self {
38
+ Ok ( Self {
30
39
column_strategies : column_layout_writers,
31
40
dtype,
32
41
row_count : 0 ,
33
- }
42
+ } )
34
43
}
35
44
36
45
pub fn try_new_with_factory < F : LayoutStrategy > (
37
46
ctx : & ArrayContext ,
38
47
dtype : & DType ,
39
48
factory : F ,
40
49
) -> VortexResult < Self > {
41
- let struct_dtype = dtype. as_struct ( ) . vortex_expect ( "dtype is not a struct" ) ;
42
- Ok ( Self :: new (
50
+ let struct_dtype = dtype
51
+ . as_struct ( )
52
+ . ok_or_else ( || vortex_err ! ( "expected StructDType" ) ) ?;
53
+ Self :: try_new (
43
54
dtype. clone ( ) ,
44
55
struct_dtype
45
56
. fields ( )
46
57
. map ( |dtype| factory. new_writer ( ctx, & dtype) )
47
58
. try_collect ( ) ?,
48
- ) )
59
+ )
49
60
}
50
61
}
51
62
@@ -98,3 +109,48 @@ impl LayoutWriter for StructLayoutWriter {
98
109
) )
99
110
}
100
111
}
112
+
113
+ #[ cfg( test) ]
114
+ mod tests {
115
+ use std:: sync:: Arc ;
116
+
117
+ use vortex_array:: ArrayContext ;
118
+ use vortex_dtype:: { DType , Nullability , PType } ;
119
+
120
+ use crate :: LayoutWriterExt ;
121
+ use crate :: layouts:: flat:: writer:: { FlatLayoutOptions , FlatLayoutWriter } ;
122
+ use crate :: layouts:: struct_:: writer:: StructLayoutWriter ;
123
+
124
+ #[ test]
125
+ #[ should_panic]
126
+ fn fails_on_duplicate_field ( ) {
127
+ StructLayoutWriter :: try_new (
128
+ DType :: Struct (
129
+ Arc :: new (
130
+ [
131
+ ( "a" , DType :: Primitive ( PType :: I32 , Nullability :: NonNullable ) ) ,
132
+ ( "a" , DType :: Primitive ( PType :: I32 , Nullability :: NonNullable ) ) ,
133
+ ]
134
+ . into_iter ( )
135
+ . collect ( ) ,
136
+ ) ,
137
+ Nullability :: NonNullable ,
138
+ ) ,
139
+ vec ! [
140
+ FlatLayoutWriter :: new(
141
+ ArrayContext :: empty( ) ,
142
+ DType :: Primitive ( PType :: I32 , Nullability :: NonNullable ) ,
143
+ FlatLayoutOptions :: default ( ) ,
144
+ )
145
+ . boxed( ) ,
146
+ FlatLayoutWriter :: new(
147
+ ArrayContext :: empty( ) ,
148
+ DType :: Primitive ( PType :: I32 , Nullability :: NonNullable ) ,
149
+ FlatLayoutOptions :: default ( ) ,
150
+ )
151
+ . boxed( ) ,
152
+ ] ,
153
+ )
154
+ . unwrap ( ) ;
155
+ }
156
+ }
0 commit comments