11use std:: iter;
2+ use std:: sync:: Arc ;
23
34use arbitrary:: { Arbitrary , Result , Unstructured } ;
45use arrow_buffer:: BooleanBuffer ;
6+ use builders:: ListBuilder ;
7+ use num_traits:: { AsPrimitive , PrimInt } ;
58use vortex_dtype:: { DType , NativePType , Nullability , PType } ;
69use vortex_error:: { VortexExpect , VortexUnwrap } ;
10+ use vortex_scalar:: arbitrary:: random_scalar;
11+ use vortex_scalar:: Scalar ;
712
813use super :: { BoolArray , ChunkedArray , NullArray , PrimitiveArray , StructArray } ;
914use crate :: array:: { VarBinArray , VarBinViewArray } ;
15+ use crate :: builders:: ArrayBuilder ;
1016use crate :: validity:: Validity ;
11- use crate :: { ArrayDType , ArrayData , IntoArrayData as _, IntoArrayVariant } ;
17+ use crate :: { builders , ArrayDType , ArrayData , IntoArrayData as _, IntoArrayVariant } ;
1218
1319impl < ' a > Arbitrary < ' a > for ArrayData {
1420 fn arbitrary ( u : & mut Unstructured < ' a > ) -> Result < Self > {
@@ -81,10 +87,7 @@ fn random_array(u: &mut Unstructured, dtype: &DType, len: Option<usize>) -> Resu
8187 . vortex_unwrap ( )
8288 . into_array ( ) )
8389 }
84- // TOOD(joe): add arbitrary list
85- DType :: List ( ..) => {
86- todo ! ( "List arrays are not implemented" )
87- }
90+ DType :: List ( ldt, n) => random_list ( u, ldt, n) ,
8891 DType :: Extension ( ..) => {
8992 todo ! ( "Extension arrays are not implemented" )
9093 }
@@ -102,6 +105,46 @@ fn random_array(u: &mut Unstructured, dtype: &DType, len: Option<usize>) -> Resu
102105 }
103106}
104107
108+ fn random_list ( u : & mut Unstructured , ldt : & Arc < DType > , n : & Nullability ) -> Result < ArrayData > {
109+ match u. int_in_range ( 0 ..=5 ) ? {
110+ 0 => random_list_offset :: < i16 > ( u, ldt, n) ,
111+ 1 => random_list_offset :: < i32 > ( u, ldt, n) ,
112+ 2 => random_list_offset :: < i64 > ( u, ldt, n) ,
113+ 3 => random_list_offset :: < u16 > ( u, ldt, n) ,
114+ 4 => random_list_offset :: < u32 > ( u, ldt, n) ,
115+ 5 => random_list_offset :: < u64 > ( u, ldt, n) ,
116+ _ => unreachable ! ( "int_in_range returns a value in the above range" ) ,
117+ }
118+ }
119+
120+ fn random_list_offset < O > (
121+ u : & mut Unstructured ,
122+ ldt : & Arc < DType > ,
123+ n : & Nullability ,
124+ ) -> Result < ArrayData >
125+ where
126+ O : PrimInt + NativePType ,
127+ Scalar : From < O > ,
128+ usize : AsPrimitive < O > ,
129+ {
130+ let list_len = u. int_in_range ( 0 ..=20 ) ?;
131+ let mut builder = ListBuilder :: < O > :: with_capacity ( ldt. clone ( ) , * n, 1 ) ;
132+ for _ in 0 ..list_len {
133+ if matches ! ( n, Nullability :: Nullable ) || u. arbitrary :: < bool > ( ) ? {
134+ let elem_len = u. int_in_range ( 0 ..=20 ) ?;
135+ let elem = ( 0 ..elem_len)
136+ . map ( |_| random_scalar ( u, ldt) )
137+ . collect :: < Result < Vec < _ > > > ( ) ?;
138+ builder
139+ . append_value ( Scalar :: list ( ldt. clone ( ) , elem, * n) . as_list ( ) )
140+ . vortex_expect ( "can append value" ) ;
141+ } else {
142+ builder. append_null ( ) ;
143+ }
144+ }
145+ Ok ( builder. finish ( ) . vortex_expect ( "builder cannot error" ) )
146+ }
147+
105148fn split_number_into_parts ( n : usize , parts : usize ) -> Vec < usize > {
106149 let reminder = n % parts;
107150 let division = ( n - reminder) / parts;
0 commit comments