## Coverage Report

#### Created: 2025-08-26 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /Users/andrewlamb/Software/arrow-rs/arrow-array/src/builder/generic_list_builder.rs

    Line
    Count
    Source
    1
    // Licensed to the Apache Software Foundation (ASF) under one
    2
    // or more contributor license agreements.  See the NOTICE file
    3
    // distributed with this work for additional information
    4
    // regarding copyright ownership.  The ASF licenses this file
    5
    // to you under the Apache License, Version 2.0 (the
    6
    // "License"); you may not use this file except in compliance
    7
    // with the License.  You may obtain a copy of the License at
    8
    //
    9
    //   http://www.apache.org/licenses/LICENSE-2.0
    10
    //
    11
    // Unless required by applicable law or agreed to in writing,
    12
    // software distributed under the License is distributed on an
    13
    // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14
    // KIND, either express or implied.  See the License for the
    15
    // specific language governing permissions and limitations
    16
    // under the License.
    17
    18
    use crate::builder::ArrayBuilder;
    19
    use crate::{Array, ArrayRef, GenericListArray, OffsetSizeTrait};
    20
    use arrow_buffer::NullBufferBuilder;
    21
    use arrow_buffer::{Buffer, OffsetBuffer};
    22
    use arrow_schema::{Field, FieldRef};
    23
    use std::any::Any;
    24
    use std::sync::Arc;
    25
    26
    /// Builder for [`GenericListArray`]
    27
    ///
    28
    /// Use [`ListBuilder`] to build [`ListArray`]s and [`LargeListBuilder`] to build [`LargeListArray`]s.
    29
    ///
    30
    /// # Example
    31
    ///
    32
    /// Here is code that constructs a ListArray with the contents:
    33
    /// `[[A,B,C], [], NULL, [D], [NULL, F]]`
    34
    ///
    35
    /// ```
    36
    /// # use std::sync::Arc;
    37
    /// # use arrow_array::{builder::ListBuilder, builder::StringBuilder, ArrayRef, StringArray, Array};
    38
    /// #
    39
    /// let values_builder = StringBuilder::new();
    40
    /// let mut builder = ListBuilder::new(values_builder);
    41
    ///
    42
    /// // [A, B, C]
    43
    /// builder.values().append_value("A");
    44
    /// builder.values().append_value("B");
    45
    /// builder.values().append_value("C");
    46
    /// builder.append(true);
    47
    ///
    48
    /// // [ ] (empty list)
    49
    /// builder.append(true);
    50
    ///
    51
    /// // Null
    52
    /// builder.append(false);
    53
    ///
    54
    /// // [D]
    55
    /// builder.values().append_value("D");
    56
    /// builder.append(true);
    57
    ///
    58
    /// // [NULL, F]
    59
    /// builder.values().append_null();
    60
    /// builder.values().append_value("F");
    61
    /// builder.append(true);
    62
    ///
    63
    /// // Build the array
    64
    /// let array = builder.finish();
    65
    ///
    66
    /// // Values is a string array
    67
    /// // "A", "B" "C", "?", "D", NULL, "F"
    68
    /// assert_eq!(
    69
    ///   array.values().as_ref(),
    70
    ///   &StringArray::from(vec![
    71
    ///     Some("A"), Some("B"), Some("C"),
    72
    ///     Some("D"), None, Some("F")
    73
    ///   ])
    74
    /// );
    75
    ///
    76
    /// // Offsets are indexes into the values array
    77
    /// assert_eq!(
    78
    ///   array.value_offsets(),
    79
    ///   &[0, 3, 3, 3, 4, 6]
    80
    /// );
    81
    /// ```
    82
    ///
    83
    /// [`ListBuilder`]: crate::builder::ListBuilder
    84
    /// [`ListArray`]: crate::array::ListArray
    85
    /// [`LargeListBuilder`]: crate::builder::LargeListBuilder
    86
    /// [`LargeListArray`]: crate::array::LargeListArray
    87
    #[derive(Debug)]
    88
    pub struct GenericListBuilder<OffsetSize: OffsetSizeTrait, T: ArrayBuilder> {
    89
        offsets_builder: Vec<OffsetSize>,
    90
        null_buffer_builder: NullBufferBuilder,
    91
        values_builder: T,
    92
        field: Option<FieldRef>,
    93
    }
    94
    95
    impl<O: OffsetSizeTrait, T: ArrayBuilder + Default> Default for GenericListBuilder<O, T> {
    96
        fn default() -> Self {
    97
            Self::new(T::default())
    98
        }
    99
    }
    100
    101
    impl<OffsetSize: OffsetSizeTrait, T: ArrayBuilder> GenericListBuilder<OffsetSize, T> {
    102
        /// Creates a new [`GenericListBuilder`] from a given values array builder
    103
    12
        pub fn new(values_builder: T) -> Self {
    104
    12
            let capacity = values_builder.len();
    105
    12
            Self::with_capacity(values_builder, capacity)
    106
    12
        }
    107
    108
        /// Creates a new [`GenericListBuilder`] from a given values array builder
    109
        /// `capacity` is the number of items to pre-allocate space for in this builder
    110
    12
        pub fn with_capacity(values_builder: T, capacity: usize) -> Self {
    111
    12
            let mut offsets_builder = Vec::with_capacity(capacity + 1);
    112
    12
            offsets_builder.push(OffsetSize::zero());
    113
    12
            Self {
    114
    12
                offsets_builder,
    115
    12
                null_buffer_builder: NullBufferBuilder::new(capacity),
    116
    12
                values_builder,
    117
    12
                field: None,
    118
    12
            }
    119
    12
        }
    120
    121
        /// Override the field passed to [`GenericListArray::new`]
    122
        ///
    123
        /// By default a nullable field is created with the name `item`
    124
        ///
    125
        /// Note: [`Self::finish`] and [`Self::finish_cloned`] will panic if the
    126
        /// field's data type does not match that of `T`
    127
    0
        pub fn with_field(self, field: impl Into<FieldRef>) -> Self {
    128
    0
            Self {
    129
    0
                field: Some(field.into()),
    130
    0
                ..self
    131
    0
            }
    132
    0
        }
    133
    }
    134
    135
    impl<OffsetSize: OffsetSizeTrait, T: ArrayBuilder> ArrayBuilder
    136
        for GenericListBuilder<OffsetSize, T>
    137
    where
    138
        T: 'static,
    139
    {
    140
        /// Returns the builder as a non-mutable `Any` reference.
    141
    0
        fn as_any(&self) -> &dyn Any {
    142
    0
            self
    143
    0
        }
    144
    145
        /// Returns the builder as a mutable `Any` reference.
    146
    2
        fn as_any_mut(&mut self) -> &mut dyn Any {
    147
    2
            self
    148
    2
        }
    149
    150
        /// Returns the boxed builder as a box of `Any`.
    151
    0
        fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
    152
    0
            self
    153
    0
        }
    154
    155
        /// Returns the number of array slots in the builder
    156
    7
        fn len(&self) -> usize {
    157
    7
            self.null_buffer_builder.len()
    158
    7
        }
    159
    160
        /// Builds the array and reset this builder.
    161
    5
        fn finish(&mut self) -> ArrayRef {
    162
    5
            Arc::new(self.finish())
    163
    5
        }
    164
    165
        /// Builds the array without resetting the builder.
    166
    0
        fn finish_cloned(&self) -> ArrayRef {
    167
    0
            Arc::new(self.finish_cloned())
    168
    0
        }
    169
    }
    170
    171
    impl<OffsetSize: OffsetSizeTrait, T: ArrayBuilder> GenericListBuilder<OffsetSize, T>
    172
    where
    173
        T: 'static,
    174
    {
    175
        /// Returns the child array builder as a mutable reference.
    176
        ///
    177
        /// This mutable reference can be used to append values into the child array builder,
    178
        /// but you must call [`append`](#method.append) to delimit each distinct list value.
    179
    16
        pub fn values(&mut self) -> &mut T {
    180
    16
            &mut self.values_builder
    181
    16
        }
    182
    183
        /// Returns the child array builder as an immutable reference
    184
        pub fn values_ref(&self) -> &T {
    185
            &self.values_builder
    186
        }
    187
    188
        /// Finish the current variable-length list array slot
    189
        ///
    190
        /// # Panics
    191
        ///
    192
        /// Panics if the length of [`Self::values`] exceeds `OffsetSize::MAX`
    193
        #[inline]
    194
    18
        pub fn append(&mut self, is_valid: bool) {
    195
    18
            self.offsets_builder.push(self.next_offset());
    196
    18
            self.null_buffer_builder.append(is_valid);
    197
    18
        }
    198
    199
        /// Returns the next offset
    200
        ///
    201
        /// # Panics
    202
        ///
    203
        /// Panics if the length of [`Self::values`] exceeds `OffsetSize::MAX`
    204
        #[inline]
    205
    18
        fn next_offset(&self) -> OffsetSize {
    206
    18
            OffsetSize::from_usize(self.values_builder.len()).unwrap()
    207
    18
        }
    208
    209
        /// Append a value to this [`GenericListBuilder`]
    210
        ///
    211
        /// ```
    212
        /// # use arrow_array::builder::{Int32Builder, ListBuilder};
    213
        /// # use arrow_array::cast::AsArray;
    214
        /// # use arrow_array::{Array, Int32Array};
    215
        /// # use arrow_array::types::Int32Type;
    216
        /// let mut builder = ListBuilder::new(Int32Builder::new());
    217
        ///
    218
        /// builder.append_value([Some(1), Some(2), Some(3)]);
    219
        /// builder.append_value([]);
    220
        /// builder.append_value([None]);
    221
        ///
    222
        /// let array = builder.finish();
    223
        /// assert_eq!(array.len(), 3);
    224
        ///
    225
        /// assert_eq!(array.value_offsets(), &[0, 3, 3, 4]);
    226
        /// let values = array.values().as_primitive::<Int32Type>();
    227
        /// assert_eq!(values, &Int32Array::from(vec![Some(1), Some(2), Some(3), None]));
    228
        /// ```
    229
        ///
    230
        /// This is an alternative API to appending directly to [`Self::values`] and
    231
        /// delimiting the result with [`Self::append`]
    232
        ///
    233
        /// ```
    234
        /// # use arrow_array::builder::{Int32Builder, ListBuilder};
    235
        /// # use arrow_array::cast::AsArray;
    236
        /// # use arrow_array::{Array, Int32Array};
    237
        /// # use arrow_array::types::Int32Type;
    238
        /// let mut builder = ListBuilder::new(Int32Builder::new());
    239
        ///
    240
        /// builder.values().append_value(1);
    241
        /// builder.values().append_value(2);
    242
        /// builder.values().append_value(3);
    243
        /// builder.append(true);
    244
        /// builder.append(true);
    245
        /// builder.values().append_null();
    246
        /// builder.append(true);
    247
        ///
    248
        /// let array = builder.finish();
    249
        /// assert_eq!(array.len(), 3);
    250
        ///
    251
        /// assert_eq!(array.value_offsets(), &[0, 3, 3, 4]);
    252
        /// let values = array.values().as_primitive::<Int32Type>();
    253
        /// assert_eq!(values, &Int32Array::from(vec![Some(1), Some(2), Some(3), None]));
    254
        /// ```
    255
        #[inline]
    256
        pub fn append_value<I, V>(&mut self, i: I)
    257
        where
    258
            T: Extend<Option<V>>,
    259
            I: IntoIterator<Item = Option<V>>,
    260
        {
    261
            self.extend(std::iter::once(Some(i)))
    262
        }
    263
    264
        /// Append a null to this [`GenericListBuilder`]
    265
        ///
    266
        /// See [`Self::append_value`] for an example use.
    267
        #[inline]
    268
        pub fn append_null(&mut self) {
    269
            self.offsets_builder.push(self.next_offset());
    270
            self.null_buffer_builder.append_null();
    271
        }
    272
    273
        /// Appends `n` `null`s into the builder.
    274
        #[inline]
    275
        pub fn append_nulls(&mut self, n: usize) {
    276
            let next_offset = self.next_offset();
    277
            self.offsets_builder
    278
                .extend(std::iter::repeat_n(next_offset, n));
    279
            self.null_buffer_builder.append_n_nulls(n);
    280
        }
    281
    282
        /// Appends an optional value into this [`GenericListBuilder`]
    283
        ///
    284
        /// If `Some` calls [`Self::append_value`] otherwise calls [`Self::append_null`]
    285
        #[inline]
    286
        pub fn append_option<I, V>(&mut self, i: Option<I>)
    287
        where
    288
            T: Extend<Option<V>>,
    289
            I: IntoIterator<Item = Option<V>>,
    290
        {
    291
            match i {
    292
                Some(i) => self.append_value(i),
    293
                None => self.append_null(),
    294
            }
    295
        }
    296
    297
        /// Builds the [`GenericListArray`] and reset this builder.
    298
    12
        pub fn finish(&mut self) -> GenericListArray<OffsetSize> {
    299
    12
            let values = self.values_builder.finish();
    300
    12
            let nulls = self.null_buffer_builder.finish();
    301
    302
    12
            let offsets = Buffer::from_vec(std::mem::take(&mut self.offsets_builder));
    303
            // Safety: Safe by construction
    304
    12
            let offsets = unsafe { OffsetBuffer::new_unchecked(offsets.into()) };
    305
    12
            self.offsets_builder.push(OffsetSize::zero());
    306
    307
    12
            let field = match &self.field {
    308
    0
                Some(f) => f.clone(),
    309
    12
                None => Arc::new(Field::new_list_field(values.data_type().clone(), true)),
    310
            };
    311
    312
    12
            GenericListArray::new(field, offsets, values, nulls)
    313
    12
        }
    314
    315
        /// Builds the [`GenericListArray`] without resetting the builder.
    316
    0
        pub fn finish_cloned(&self) -> GenericListArray<OffsetSize> {
    317
    0
            let values = self.values_builder.finish_cloned();
    318
    0
            let nulls = self.null_buffer_builder.finish_cloned();
    319
    320
    0
            let offsets = Buffer::from_slice_ref(self.offsets_builder.as_slice());
    321
            // Safety: safe by construction
    322
    0
            let offsets = unsafe { OffsetBuffer::new_unchecked(offsets.into()) };
    323
    324
    0
            let field = match &self.field {
    325
    0
                Some(f) => f.clone(),
    326
    0
                None => Arc::new(Field::new_list_field(values.data_type().clone(), true)),
    327
            };
    328
    329
    0
            GenericListArray::new(field, offsets, values, nulls)
    330
    0
        }
    331
    332
        /// Returns the current offsets buffer as a slice
    333
        pub fn offsets_slice(&self) -> &[OffsetSize] {
    334
            self.offsets_builder.as_slice()
    335
        }
    336
    337
        /// Returns the current null buffer as a slice
    338
        pub fn validity_slice(&self) -> Option<&[u8]> {
    339
            self.null_buffer_builder.as_slice()
    340
        }
    341
    }
    342
    343
    impl<O, B, V, E> Extend<Option<V>> for GenericListBuilder<O, B>
    344
    where
    345
        O: OffsetSizeTrait,
    346
        B: ArrayBuilder + Extend<E>,
    347
        V: IntoIterator<Item = E>,
    348
    {
    349
        #[inline]
    350
        fn extend<T: IntoIterator<Item = Option<V>>>(&mut self, iter: T) {
    351
            for v in iter {
    352
                match v {
    353
                    Some(elements) => {
    354
                        self.values_builder.extend(elements);
    355
                        self.append(true);
    356
                    }
    357
                    None => self.append(false),
    358
                }
    359
            }
    360
        }
    361
    }
    362
    363
    #[cfg(test)]
    364
    mod tests {
    365
        use super::*;
    366
        use crate::builder::{make_builder, Int32Builder, ListBuilder};
    367
        use crate::cast::AsArray;
    368
        use crate::types::Int32Type;
    369
        use crate::Int32Array;
    370
        use arrow_schema::DataType;
    371
    372
        fn _test_generic_list_array_builder<O: OffsetSizeTrait>() {
    373
            let values_builder = Int32Builder::with_capacity(10);
    374
            let mut builder = GenericListBuilder::<O, _>::new(values_builder);
    375
    376
            //  [[0, 1, 2], [3, 4, 5], [6, 7]]
    377
            builder.values().append_value(0);
    378
            builder.values().append_value(1);
    379
            builder.values().append_value(2);
    380
            builder.append(true);
    381
            builder.values().append_value(3);
    382
            builder.values().append_value(4);
    383
            builder.values().append_value(5);
    384
            builder.append(true);
    385
            builder.values().append_value(6);
    386
            builder.values().append_value(7);
    387
            builder.append(true);
    388
            let list_array = builder.finish();
    389
    390
            let list_values = list_array.values().as_primitive::<Int32Type>();
    391
            assert_eq!(list_values.values(), &[0, 1, 2, 3, 4, 5, 6, 7]);
    392
            assert_eq!(list_array.value_offsets(), [0, 3, 6, 8].map(O::usize_as));
    393
            assert_eq!(DataType::Int32, list_array.value_type());
    394
            assert_eq!(3, list_array.len());
    395
            assert_eq!(0, list_array.null_count());
    396
            assert_eq!(O::from_usize(6).unwrap(), list_array.value_offsets()[2]);
    397
            assert_eq!(O::from_usize(2).unwrap(), list_array.value_length(2));
    398
            for i in 0..3 {
    399
                assert!(list_array.is_valid(i));
    400
                assert!(!list_array.is_null(i));
    401
            }
    402
        }
    403
    404
        #[test]
    405
        fn test_list_array_builder() {
    406
            _test_generic_list_array_builder::<i32>()
    407
        }
    408
    409
        #[test]
    410
        fn test_large_list_array_builder() {
    411
            _test_generic_list_array_builder::<i64>()
    412
        }
    413
    414
        fn _test_generic_list_array_builder_nulls<O: OffsetSizeTrait>() {
    415
            let values_builder = Int32Builder::with_capacity(10);
    416
            let mut builder = GenericListBuilder::<O, _>::new(values_builder);
    417
    418
            //  [[0, 1, 2], null, [3, null, 5], [6, 7], null, null, [8]]
    419
            builder.values().append_value(0);
    420
            builder.values().append_value(1);
    421
            builder.values().append_value(2);
    422
            builder.append(true);
    423
            builder.append(false);
    424
            builder.values().append_value(3);
    425
            builder.values().append_null();
    426
            builder.values().append_value(5);
    427
            builder.append(true);
    428
            builder.values().append_value(6);
    429
            builder.values().append_value(7);
    430
            builder.append(true);
    431
            builder.append_nulls(2);
    432
            builder.values().append_value(8);
    433
            builder.append(true);
    434
    435
            let list_array = builder.finish();
    436
    437
            assert_eq!(DataType::Int32, list_array.value_type());
    438
            assert_eq!(7, list_array.len());
    439
            assert_eq!(3, list_array.null_count());
    440
            assert_eq!(O::from_usize(3).unwrap(), list_array.value_offsets()[2]);
    441
            assert_eq!(O::from_usize(9).unwrap(), list_array.value_offsets()[7]);
    442
            assert_eq!(O::from_usize(3).unwrap(), list_array.value_length(2));
    443
            assert!(list_array.is_null(4));
    444
            assert!(list_array.is_null(5));
    445
        }
    446
    447
        #[test]
    448
        fn test_list_array_builder_nulls() {
    449
            _test_generic_list_array_builder_nulls::<i32>()
    450
        }
    451
    452
        #[test]
    453
        fn test_large_list_array_builder_nulls() {
    454
            _test_generic_list_array_builder_nulls::<i64>()
    455
        }
    456
    457
        #[test]
    458
        fn test_list_array_builder_finish() {
    459
            let values_builder = Int32Array::builder(5);
    460
            let mut builder = ListBuilder::new(values_builder);
    461
    462
            builder.values().append_slice(&[1, 2, 3]);
    463
            builder.append(true);
    464
            builder.values().append_slice(&[4, 5, 6]);
    465
            builder.append(true);
    466
    467
            let mut arr = builder.finish();
    468
            assert_eq!(2, arr.len());
    469
            assert!(builder.is_empty());
    470
    471
            builder.values().append_slice(&[7, 8, 9]);
    472
            builder.append(true);
    473
            arr = builder.finish();
    474
            assert_eq!(1, arr.len());
    475
            assert!(builder.is_empty());
    476
        }
    477
    478
        #[test]
    479
        fn test_list_array_builder_finish_cloned() {
    480
            let values_builder = Int32Array::builder(5);
    481
            let mut builder = ListBuilder::new(values_builder);
    482
    483
            builder.values().append_slice(&[1, 2, 3]);
    484
            builder.append(true);
    485
            builder.values().append_slice(&[4, 5, 6]);
    486
            builder.append(true);
    487
    488
            let mut arr = builder.finish_cloned();
    489
            assert_eq!(2, arr.len());
    490
            assert!(!builder.is_empty());
    491
    492
            builder.values().append_slice(&[7, 8, 9]);
    493
            builder.append(true);
    494
            arr = builder.finish();
    495
            assert_eq!(3, arr.len());
    496
            assert!(builder.is_empty());
    497
        }
    498
    499
        #[test]
    500
        fn test_list_list_array_builder() {
    501
            let primitive_builder = Int32Builder::with_capacity(10);
    502
            let values_builder = ListBuilder::new(primitive_builder);
    503
            let mut builder = ListBuilder::new(values_builder);
    504
    505
            //  [[[1, 2], [3, 4]], [[5, 6, 7], null, [8]], null, [[9, 10]]]
    506
            builder.values().values().append_value(1);
    507
            builder.values().values().append_value(2);
    508
            builder.values().append(true);
    509
            builder.values().values().append_value(3);
    510
            builder.values().values().append_value(4);
    511
            builder.values().append(true);
    512
            builder.append(true);
    513
    514
            builder.values().values().append_value(5);
    515
            builder.values().values().append_value(6);
    516
            builder.values().values().append_value(7);
    517
            builder.values().append(true);
    518
            builder.values().append(false);
    519
            builder.values().values().append_value(8);
    520
            builder.values().append(true);
    521
            builder.append(true);
    522
    523
            builder.append(false);
    524
    525
            builder.values().values().append_value(9);
    526
            builder.values().values().append_value(10);
    527
            builder.values().append(true);
    528
            builder.append(true);
    529
    530
            let l1 = builder.finish();
    531
    532
            assert_eq!(4, l1.len());
    533
            assert_eq!(1, l1.null_count());
    534
    535
            assert_eq!(l1.value_offsets(), &[0, 2, 5, 5, 6]);
    536
            let l2 = l1.values().as_list::<i32>();
    537
    538
            assert_eq!(6, l2.len());
    539
            assert_eq!(1, l2.null_count());
    540
            assert_eq!(l2.value_offsets(), &[0, 2, 4, 7, 7, 8, 10]);
    541
    542
            let i1 = l2.values().as_primitive::<Int32Type>();
    543
            assert_eq!(10, i1.len());
    544
            assert_eq!(0, i1.null_count());
    545
            assert_eq!(i1.values(), &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
    546
        }
    547
    548
        #[test]
    549
        fn test_extend() {
    550
            let mut builder = ListBuilder::new(Int32Builder::new());
    551
            builder.extend([
    552
                Some(vec![Some(1), Some(2), Some(7), None]),
    553
                Some(vec![]),
    554
                Some(vec![Some(4), Some(5)]),
    555
                None,
    556
            ]);
    557
    558
            let array = builder.finish();
    559
            assert_eq!(array.value_offsets(), [0, 4, 4, 6, 6]);
    560
            assert_eq!(array.null_count(), 1);
    561
            assert_eq!(array.logical_null_count(), 1);
    562
            assert!(array.is_null(3));
    563
            let elements = array.values().as_primitive::<Int32Type>();
    564
            assert_eq!(elements.values(), &[1, 2, 7, 0, 4, 5]);
    565
            assert_eq!(elements.null_count(), 1);
    566
            assert_eq!(elements.logical_null_count(), 1);
    567
            assert!(elements.is_null(3));
    568
        }
    569
    570
        #[test]
    571
        fn test_boxed_primitive_array_builder() {
    572
            let values_builder = make_builder(&DataType::Int32, 5);
    573
            let mut builder = ListBuilder::new(values_builder);
    574
    575
            builder
    576
                .values()
    577
                .as_any_mut()
    578
                .downcast_mut::<Int32Builder>()
    579
                .expect("should be an Int32Builder")
    580
                .append_slice(&[1, 2, 3]);
    581
            builder.append(true);
    582
    583
            builder
    584
                .values()
    585
                .as_any_mut()
    586
                .downcast_mut::<Int32Builder>()
    587
                .expect("should be an Int32Builder")
    588
                .append_slice(&[4, 5, 6]);
    589
            builder.append(true);
    590
    591
            let arr = builder.finish();
    592
            assert_eq!(2, arr.len());
    593
    594
            let elements = arr.values().as_primitive::<Int32Type>();
    595
            assert_eq!(elements.values(), &[1, 2, 3, 4, 5, 6]);
    596
        }
    597
    598
        #[test]
    599
        fn test_boxed_list_list_array_builder() {
    600
            // This test is same as `test_list_list_array_builder` but uses boxed builders.
    601
            let values_builder = make_builder(
    602
                &DataType::List(Arc::new(Field::new_list_field(DataType::Int32, true))),
    603
                10,
    604
            );
    605
            test_boxed_generic_list_generic_list_array_builder::<i32>(values_builder);
    606
        }
    607
    608
        #[test]
    609
        fn test_boxed_large_list_large_list_array_builder() {
    610
            // This test is same as `test_list_list_array_builder` but uses boxed builders.
    611
            let values_builder = make_builder(
    612
                &DataType::LargeList(Arc::new(Field::new_list_field(DataType::Int32, true))),
    613
                10,
    614
            );
    615
            test_boxed_generic_list_generic_list_array_builder::<i64>(values_builder);
    616
        }
    617
    618
        fn test_boxed_generic_list_generic_list_array_builder<O: OffsetSizeTrait + PartialEq>(
    619
            values_builder: Box<dyn ArrayBuilder>,
    620
        ) {
    621
            let mut builder: GenericListBuilder<O, Box<dyn ArrayBuilder>> =
    622
                GenericListBuilder::<O, Box<dyn ArrayBuilder>>::new(values_builder);
    623
    624
            //  [[[1, 2], [3, 4]], [[5, 6, 7], null, [8]], null, [[9, 10]]]
    625
            builder
    626
                .values()
    627
                .as_any_mut()
    628
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    629
                .expect("should be an (Large)ListBuilder")
    630
                .values()
    631
                .as_any_mut()
    632
                .downcast_mut::<Int32Builder>()
    633
                .expect("should be an Int32Builder")
    634
                .append_value(1);
    635
            builder
    636
                .values()
    637
                .as_any_mut()
    638
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    639
                .expect("should be an (Large)ListBuilder")
    640
                .values()
    641
                .as_any_mut()
    642
                .downcast_mut::<Int32Builder>()
    643
                .expect("should be an Int32Builder")
    644
                .append_value(2);
    645
            builder
    646
                .values()
    647
                .as_any_mut()
    648
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    649
                .expect("should be an (Large)ListBuilder")
    650
                .append(true);
    651
            builder
    652
                .values()
    653
                .as_any_mut()
    654
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    655
                .expect("should be an (Large)ListBuilder")
    656
                .values()
    657
                .as_any_mut()
    658
                .downcast_mut::<Int32Builder>()
    659
                .expect("should be an Int32Builder")
    660
                .append_value(3);
    661
            builder
    662
                .values()
    663
                .as_any_mut()
    664
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    665
                .expect("should be an (Large)ListBuilder")
    666
                .values()
    667
                .as_any_mut()
    668
                .downcast_mut::<Int32Builder>()
    669
                .expect("should be an Int32Builder")
    670
                .append_value(4);
    671
            builder
    672
                .values()
    673
                .as_any_mut()
    674
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    675
                .expect("should be an (Large)ListBuilder")
    676
                .append(true);
    677
            builder.append(true);
    678
    679
            builder
    680
                .values()
    681
                .as_any_mut()
    682
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    683
                .expect("should be an (Large)ListBuilder")
    684
                .values()
    685
                .as_any_mut()
    686
                .downcast_mut::<Int32Builder>()
    687
                .expect("should be an Int32Builder")
    688
                .append_value(5);
    689
            builder
    690
                .values()
    691
                .as_any_mut()
    692
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    693
                .expect("should be an (Large)ListBuilder")
    694
                .values()
    695
                .as_any_mut()
    696
                .downcast_mut::<Int32Builder>()
    697
                .expect("should be an Int32Builder")
    698
                .append_value(6);
    699
            builder
    700
                .values()
    701
                .as_any_mut()
    702
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    703
                .expect("should be an (Large)ListBuilder")
    704
                .values()
    705
                .as_any_mut()
    706
                .downcast_mut::<Int32Builder>()
    707
                .expect("should be an (Large)ListBuilder")
    708
                .append_value(7);
    709
            builder
    710
                .values()
    711
                .as_any_mut()
    712
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    713
                .expect("should be an (Large)ListBuilder")
    714
                .append(true);
    715
            builder
    716
                .values()
    717
                .as_any_mut()
    718
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    719
                .expect("should be an (Large)ListBuilder")
    720
                .append(false);
    721
            builder
    722
                .values()
    723
                .as_any_mut()
    724
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    725
                .expect("should be an (Large)ListBuilder")
    726
                .values()
    727
                .as_any_mut()
    728
                .downcast_mut::<Int32Builder>()
    729
                .expect("should be an Int32Builder")
    730
                .append_value(8);
    731
            builder
    732
                .values()
    733
                .as_any_mut()
    734
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    735
                .expect("should be an (Large)ListBuilder")
    736
                .append(true);
    737
            builder.append(true);
    738
    739
            builder.append(false);
    740
    741
            builder
    742
                .values()
    743
                .as_any_mut()
    744
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    745
                .expect("should be an (Large)ListBuilder")
    746
                .values()
    747
                .as_any_mut()
    748
                .downcast_mut::<Int32Builder>()
    749
                .expect("should be an Int32Builder")
    750
                .append_value(9);
    751
            builder
    752
                .values()
    753
                .as_any_mut()
    754
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    755
                .expect("should be an (Large)ListBuilder")
    756
                .values()
    757
                .as_any_mut()
    758
                .downcast_mut::<Int32Builder>()
    759
                .expect("should be an Int32Builder")
    760
                .append_value(10);
    761
            builder
    762
                .values()
    763
                .as_any_mut()
    764
                .downcast_mut::<GenericListBuilder<O, Box<dyn ArrayBuilder>>>()
    765
                .expect("should be an (Large)ListBuilder")
    766
                .append(true);
    767
            builder.append(true);
    768
    769
            let l1 = builder.finish();
    770
    771
            assert_eq!(4, l1.len());
    772
            assert_eq!(1, l1.null_count());
    773
    774
            assert_eq!(l1.value_offsets(), &[0, 2, 5, 5, 6].map(O::usize_as));
    775
            let l2 = l1.values().as_list::<O>();
    776
    777
            assert_eq!(6, l2.len());
    778
            assert_eq!(1, l2.null_count());
    779
            assert_eq!(l2.value_offsets(), &[0, 2, 4, 7, 7, 8, 10].map(O::usize_as));
    780
    781
            let i1 = l2.values().as_primitive::<Int32Type>();
    782
            assert_eq!(10, i1.len());
    783
            assert_eq!(0, i1.null_count());
    784
            assert_eq!(i1.values(), &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
    785
        }
    786
    787
        #[test]
    788
        fn test_with_field() {
    789
            let field = Arc::new(Field::new("bar", DataType::Int32, false));
    790
            let mut builder = ListBuilder::new(Int32Builder::new()).with_field(field.clone());
    791
            builder.append_value([Some(1), Some(2), Some(3)]);
    792
            builder.append_null(); // This is fine as nullability refers to nullability of values
    793
            builder.append_value([Some(4)]);
    794
            let array = builder.finish();
    795
            assert_eq!(array.len(), 3);
    796
            assert_eq!(array.data_type(), &DataType::List(field.clone()));
    797
    798
            builder.append_value([Some(4), Some(5)]);
    799
            let array = builder.finish();
    800
            assert_eq!(array.data_type(), &DataType::List(field));
    801
            assert_eq!(array.len(), 1);
    802
        }
    803
    804
        #[test]
    805
        #[should_panic(expected = "Non-nullable field of ListArray \\\"item\\\" cannot contain nulls")]
    806
        fn test_checks_nullability() {
    807
            let field = Arc::new(Field::new_list_field(DataType::Int32, false));
    808
            let mut builder = ListBuilder::new(Int32Builder::new()).with_field(field.clone());
    809
            builder.append_value([Some(1), None]);
    810
            builder.finish();
    811
        }
    812
    813
        #[test]
    814
        #[should_panic(expected = "ListArray expected data type Int64 got Int32")]
    815
        fn test_checks_data_type() {
    816
            let field = Arc::new(Field::new_list_field(DataType::Int64, false));
    817
            let mut builder = ListBuilder::new(Int32Builder::new()).with_field(field.clone());
    818
            builder.append_value([Some(1)]);
    819
            builder.finish();
    820
        }
    821
    }