## Coverage Report

#### Created: 2025-11-17 14:14

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

    /Users/andrewlamb/Software/arrow-rs/arrow-array/src/array/boolean_array.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::array::print_long_array;
    19
    use crate::builder::BooleanBuilder;
    20
    use crate::iterator::BooleanIter;
    21
    use crate::{Array, ArrayAccessor, ArrayRef, Scalar};
    22
    use arrow_buffer::{BooleanBuffer, Buffer, MutableBuffer, NullBuffer, bit_util};
    23
    use arrow_data::{ArrayData, ArrayDataBuilder};
    24
    use arrow_schema::DataType;
    25
    use std::any::Any;
    26
    use std::sync::Arc;
    27
    28
    /// An array of [boolean values](https://arrow.apache.org/docs/format/Columnar.html#fixed-size-primitive-layout)
    29
    ///
    30
    /// # Example: From a Vec
    31
    ///
    32
    /// ```
    33
    /// # use arrow_array::{Array, BooleanArray};
    34
    /// let arr: BooleanArray = vec![true, true, false].into();
    35
    /// ```
    36
    ///
    37
    /// # Example: From an optional Vec
    38
    ///
    39
    /// ```
    40
    /// # use arrow_array::{Array, BooleanArray};
    41
    /// let arr: BooleanArray = vec![Some(true), None, Some(false)].into();
    42
    /// ```
    43
    ///
    44
    /// # Example: From an iterator
    45
    ///
    46
    /// ```
    47
    /// # use arrow_array::{Array, BooleanArray};
    48
    /// let arr: BooleanArray = (0..5).map(|x| (x % 2 == 0).then(|| x % 3 == 0)).collect();
    49
    /// let values: Vec<_> = arr.iter().collect();
    50
    /// assert_eq!(&values, &[Some(true), None, Some(false), None, Some(false)])
    51
    /// ```
    52
    ///
    53
    /// # Example: Using Builder
    54
    ///
    55
    /// ```
    56
    /// # use arrow_array::Array;
    57
    /// # use arrow_array::builder::BooleanBuilder;
    58
    /// let mut builder = BooleanBuilder::new();
    59
    /// builder.append_value(true);
    60
    /// builder.append_null();
    61
    /// builder.append_value(false);
    62
    /// let array = builder.finish();
    63
    /// let values: Vec<_> = array.iter().collect();
    64
    /// assert_eq!(&values, &[Some(true), None, Some(false)])
    65
    /// ```
    66
    ///
    67
    #[derive(Clone)]
    68
    pub struct BooleanArray {
    69
        values: BooleanBuffer,
    70
        nulls: Option<NullBuffer>,
    71
    }
    72
    73
    impl std::fmt::Debug for BooleanArray {
    74
    0
        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
    75
    0
            write!(f, "BooleanArray\n[\n")?;
    76
    0
            print_long_array(self, f, |array, index, f| {
    77
    0
                std::fmt::Debug::fmt(&array.value(index), f)
    78
    0
            })?;
    79
    0
            write!(f, "]")
    80
    0
        }
    81
    }
    82
    83
    impl BooleanArray {
    84
        /// Create a new [`BooleanArray`] from the provided values and nulls
    85
        ///
    86
        /// # Panics
    87
        ///
    88
        /// Panics if `values.len() != nulls.len()`
    89
    27
        pub fn new(values: BooleanBuffer, nulls: Option<NullBuffer>) -> Self {
    90
    27
            if let Some(n11) = nulls.as_ref() {
    91
    11
                assert_eq!(values.len(), n.len());
    92
    16
            }
    93
    27
            Self { values, nulls }
    94
    27
        }
    95
    96
        /// Create a new [`BooleanArray`] with length `len` consisting only of nulls
    97
    1
        pub fn new_null(len: usize) -> Self {
    98
    1
            Self {
    99
    1
                values: BooleanBuffer::new_unset(len),
    100
    1
                nulls: Some(NullBuffer::new_null(len)),
    101
    1
            }
    102
    1
        }
    103
    104
        /// Create a new [`Scalar`] from `value`
    105
    0
        pub fn new_scalar(value: bool) -> Scalar<Self> {
    106
    0
            let values = match value {
    107
    0
                true => BooleanBuffer::new_set(1),
    108
    0
                false => BooleanBuffer::new_unset(1),
    109
            };
    110
    0
            Scalar::new(Self::new(values, None))
    111
    0
        }
    112
    113
        /// Create a new [`BooleanArray`] from a [`Buffer`] specified by `offset` and `len`, the `offset` and `len` in bits
    114
        /// Logically convert each bit in [`Buffer`] to boolean and use it to build [`BooleanArray`].
    115
        /// using this method will make the following points self-evident:
    116
        /// * there is no `null` in the constructed [`BooleanArray`];
    117
        /// * without considering `buffer.into()`, this method is efficient because there is no need to perform pack and unpack operations on boolean;
    118
        pub fn new_from_packed(buffer: impl Into<Buffer>, offset: usize, len: usize) -> Self {
    119
            BooleanBuffer::new(buffer.into(), offset, len).into()
    120
        }
    121
    122
        /// Create a new [`BooleanArray`] from `&[u8]`
    123
        /// This method uses `new_from_packed` and constructs a [`Buffer`] using `value`, and offset is set to 0 and len is set to `value.len() * 8`
    124
        /// using this method will make the following points self-evident:
    125
        /// * there is no `null` in the constructed [`BooleanArray`];
    126
        /// * the length of the constructed [`BooleanArray`] is always a multiple of 8;
    127
    0
        pub fn new_from_u8(value: &[u8]) -> Self {
    128
    0
            BooleanBuffer::new(Buffer::from(value), 0, value.len() * 8).into()
    129
    0
        }
    130
    131
        /// Returns the length of this array.
    132
    2.73k
        pub fn len(&self) -> usize {
    133
    2.73k
            self.values.len()
    134
    2.73k
        }
    135
    136
        /// Returns whether this array is empty.
    137
    0
        pub fn is_empty(&self) -> bool {
    138
    0
            self.values.is_empty()
    139
    0
        }
    140
    141
        /// Returns a zero-copy slice of this array with the indicated offset and length.
    142
    877
        pub fn slice(&self, offset: usize, length: usize) -> Self {
    143
            Self {
    144
    877
                values: self.values.slice(offset, length),
    145
    877
                nulls: self.nulls.as_ref().map(|n| n766.slice766(offset766, length766)),
    146
            }
    147
    877
        }
    148
    149
        /// Returns a new boolean array builder
    150
    0
        pub fn builder(capacity: usize) -> BooleanBuilder {
    151
    0
            BooleanBuilder::with_capacity(capacity)
    152
    0
        }
    153
    154
        /// Returns the underlying [`BooleanBuffer`] holding all the values of this array
    155
    3.11k
        pub fn values(&self) -> &BooleanBuffer {
    156
    3.11k
            &self.values
    157
    3.11k
        }
    158
    159
        /// Returns the number of non null, true values within this array
    160
    0
        pub fn true_count(&self) -> usize {
    161
    0
            match self.nulls() {
    162
    0
                Some(nulls) => {
    163
    0
                    let null_chunks = nulls.inner().bit_chunks().iter_padded();
    164
    0
                    let value_chunks = self.values().bit_chunks().iter_padded();
    165
    0
                    null_chunks
    166
    0
                        .zip(value_chunks)
    167
    0
                        .map(|(a, b)| (a & b).count_ones() as usize)
    168
    0
                        .sum()
    169
                }
    170
    0
                None => self.values().count_set_bits(),
    171
            }
    172
    0
        }
    173
    174
        /// Returns the number of non null, false values within this array
    175
    0
        pub fn false_count(&self) -> usize {
    176
    0
            self.len() - self.null_count() - self.true_count()
    177
    0
        }
    178
    179
        /// Returns the boolean value at index `i`.
    180
        ///
    181
        /// Note: This method does not check for nulls and the value is arbitrary
    182
        /// if [`is_null`](Self::is_null) returns true for the index.
    183
        ///
    184
        /// # Safety
    185
        /// This doesn't check bounds, the caller must ensure that index < self.len()
    186
    18.4k
        pub unsafe fn value_unchecked(&self, i: usize) -> bool {
    187
    18.4k
            unsafe { self.values.value_unchecked(i) }
    188
    18.4k
        }
    189
    190
        /// Returns the boolean value at index `i`.
    191
        ///
    192
        /// Note: This method does not check for nulls and the value is arbitrary
    193
        /// if [`is_null`](Self::is_null) returns true for the index.
    194
        ///
    195
        /// # Panics
    196
        /// Panics if index `i` is out of bounds
    197
    0
        pub fn value(&self, i: usize) -> bool {
    198
    0
            assert!(
    199
    0
                i < self.len(),
    200
    0
                "Trying to access an element at index {} from a BooleanArray of length {}",
    201
                i,
    202
    0
                self.len()
    203
            );
    204
            // Safety:
    205
            // `i < self.len()
    206
    0
            unsafe { self.value_unchecked(i) }
    207
    0
        }
    208
    209
        /// Returns an iterator that returns the values of `array.value(i)` for an iterator with each element `i`
    210
        pub fn take_iter<'a>(
    211
            &'a self,
    212
            indexes: impl Iterator<Item = Option<usize>> + 'a,
    213
        ) -> impl Iterator<Item = Option<bool>> + 'a {
    214
            indexes.map(|opt_index| opt_index.map(|index| self.value(index)))
    215
        }
    216
    217
        /// Returns an iterator that returns the values of `array.value(i)` for an iterator with each element `i`
    218
        /// # Safety
    219
        ///
    220
        /// caller must ensure that the offsets in the iterator are less than the array len()
    221
        pub unsafe fn take_iter_unchecked<'a>(
    222
            &'a self,
    223
            indexes: impl Iterator<Item = Option<usize>> + 'a,
    224
        ) -> impl Iterator<Item = Option<bool>> + 'a {
    225
            indexes.map(|opt_index| opt_index.map(|index| unsafe { self.value_unchecked(index) }))
    226
        }
    227
    228
        /// Create a [`BooleanArray`] by evaluating the operation for
    229
        /// each element of the provided array
    230
        ///
    231
        /// ```
    232
        /// # use arrow_array::{BooleanArray, Int32Array};
    233
        ///
    234
        /// let array = Int32Array::from(vec![1, 2, 3, 4, 5]);
    235
        /// let r = BooleanArray::from_unary(&array, |x| x > 2);
    236
        /// assert_eq!(&r, &BooleanArray::from(vec![false, false, true, true, true]));
    237
        /// ```
    238
    5
        pub fn from_unary<T: ArrayAccessor, F>(left: T, mut op: F) -> Self
    239
    5
        where
    240
    5
            F: FnMut(T::Item) -> bool,
    241
        {
    242
    5
            let nulls = left.logical_nulls();
    243
    5
            let values = BooleanBuffer::collect_bool(left.len(), |i| unsafe {
    244
                // SAFETY: i in range 0..len
    245
    23
                op(left.value_unchecked(i))
    246
    23
            });
    247
    5
            Self::new(values, nulls)
    248
    5
        }
    249
    250
        /// Create a [`BooleanArray`] by evaluating the binary operation for
    251
        /// each element of the provided arrays
    252
        ///
    253
        /// ```
    254
        /// # use arrow_array::{BooleanArray, Int32Array};
    255
        ///
    256
        /// let a = Int32Array::from(vec![1, 2, 3, 4, 5]);
    257
        /// let b = Int32Array::from(vec![1, 2, 0, 2, 5]);
    258
        /// let r = BooleanArray::from_binary(&a, &b, |a, b| a == b);
    259
        /// assert_eq!(&r, &BooleanArray::from(vec![true, true, false, false, true]));
    260
        /// ```
    261
        ///
    262
        /// # Panics
    263
        ///
    264
        /// This function panics if left and right are not the same length
    265
        ///
    266
        pub fn from_binary<T: ArrayAccessor, S: ArrayAccessor, F>(left: T, right: S, mut op: F) -> Self
    267
        where
    268
            F: FnMut(T::Item, S::Item) -> bool,
    269
        {
    270
            assert_eq!(left.len(), right.len());
    271
    272
            let nulls = NullBuffer::union(
    273
                left.logical_nulls().as_ref(),
    274
                right.logical_nulls().as_ref(),
    275
            );
    276
            let values = BooleanBuffer::collect_bool(left.len(), |i| unsafe {
    277
                // SAFETY: i in range 0..len
    278
                op(left.value_unchecked(i), right.value_unchecked(i))
    279
            });
    280
            Self::new(values, nulls)
    281
        }
    282
    283
        /// Deconstruct this array into its constituent parts
    284
    4
        pub fn into_parts(self) -> (BooleanBuffer, Option<NullBuffer>) {
    285
    4
            (self.values, self.nulls)
    286
    4
        }
    287
    }
    288
    289
    impl Array for BooleanArray {
    290
    116
        fn as_any(&self) -> &dyn Any {
    291
    116
            self
    292
    116
        }
    293
    294
    22
        fn to_data(&self) -> ArrayData {
    295
    22
            self.clone().into()
    296
    22
        }
    297
    298
    0
        fn into_data(self) -> ArrayData {
    299
    0
            self.into()
    300
    0
        }
    301
    302
    26
        fn data_type(&self) -> &DataType {
    303
    26
            &DataType::Boolean
    304
    26
        }
    305
    306
    1
        fn slice(&self, offset: usize, length: usize) -> ArrayRef {
    307
    1
            Arc::new(self.slice(offset, length))
    308
    1
        }
    309
    310
    791
        fn len(&self) -> usize {
    311
    791
            self.values.len()
    312
    791
        }
    313
    314
    0
        fn is_empty(&self) -> bool {
    315
    0
            self.values.is_empty()
    316
    0
        }
    317
    318
    0
        fn shrink_to_fit(&mut self) {
    319
    0
            self.values.shrink_to_fit();
    320
    0
            if let Some(nulls) = &mut self.nulls {
    321
    0
                nulls.shrink_to_fit();
    322
    0
            }
    323
    0
        }
    324
    325
    0
        fn offset(&self) -> usize {
    326
    0
            self.values.offset()
    327
    0
        }
    328
    329
    3.54k
        fn nulls(&self) -> Option<&NullBuffer> {
    330
    3.54k
            self.nulls.as_ref()
    331
    3.54k
        }
    332
    333
    0
        fn logical_null_count(&self) -> usize {
    334
    0
            self.null_count()
    335
    0
        }
    336
    337
    0
        fn get_buffer_memory_size(&self) -> usize {
    338
    0
            let mut sum = self.values.inner().capacity();
    339
    0
            if let Some(x) = &self.nulls {
    340
    0
                sum += x.buffer().capacity()
    341
    0
            }
    342
    0
            sum
    343
    0
        }
    344
    345
    0
        fn get_array_memory_size(&self) -> usize {
    346
    0
            std::mem::size_of::<Self>() + self.get_buffer_memory_size()
    347
    0
        }
    348
    }
    349
    350
    impl ArrayAccessor for &BooleanArray {
    351
        type Item = bool;
    352
    353
    0
        fn value(&self, index: usize) -> Self::Item {
    354
    0
            BooleanArray::value(self, index)
    355
    0
        }
    356
    357
    18.4k
        unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
    358
    18.4k
            unsafe { BooleanArray::value_unchecked(self, index) }
    359
    18.4k
        }
    360
    }
    361
    362
    impl From<Vec<bool>> for BooleanArray {
    363
    130
        fn from(data: Vec<bool>) -> Self {
    364
    130
            let mut mut_buf = MutableBuffer::new_null(data.len());
    365
            {
    366
    130
                let mut_slice = mut_buf.as_slice_mut();
    367
    973
                for (i, b) in data.iter()130.enumerate130() {
    368
    973
                    if *b {
    369
    545
                        bit_util::set_bit(mut_slice, i);
    370
    545
                    }428
    371
                }
    372
            }
    373
    130
            let array_data = ArrayData::builder(DataType::Boolean)
    374
    130
                .len(data.len())
    375
    130
                .add_buffer(mut_buf.into());
    376
    377
    130
            let array_data = unsafe { array_data.build_unchecked() };
    378
    130
            BooleanArray::from(array_data)
    379
    130
        }
    380
    }
    381
    382
    impl From<Vec<Option<bool>>> for BooleanArray {
    383
    24
        fn from(data: Vec<Option<bool>>) -> Self {
    384
    24
            data.iter().collect()
    385
    24
        }
    386
    }
    387
    388
    impl From<ArrayData> for BooleanArray {
    389
    2.12k
        fn from(data: ArrayData) -> Self {
    390
    2.12k
            assert_eq!(
    391
    2.12k
                data.data_type(),
    392
                &DataType::Boolean,
    393
    0
                "BooleanArray expected ArrayData with type {} got {}",
    394
                DataType::Boolean,
    395
    0
                data.data_type()
    396
            );
    397
    2.12k
            assert_eq!(
    398
    2.12k
                data.buffers().len(),
    399
                1,
    400
    0
                "BooleanArray data should contain a single buffer only (values buffer)"
    401
            );
    402
    2.12k
            let values = BooleanBuffer::new(data.buffers()[0].clone(), data.offset(), data.len());
    403
    404
    2.12k
            Self {
    405
    2.12k
                values,
    406
    2.12k
                nulls: data.nulls().cloned(),
    407
    2.12k
            }
    408
    2.12k
        }
    409
    }
    410
    411
    impl From<BooleanArray> for ArrayData {
    412
    22
        fn from(array: BooleanArray) -> Self {
    413
    22
            let builder = ArrayDataBuilder::new(DataType::Boolean)
    414
    22
                .len(array.values.len())
    415
    22
                .offset(array.values.offset())
    416
    22
                .nulls(array.nulls)
    417
    22
                .buffers(vec![array.values.into_inner()]);
    418
    419
    22
            unsafe { builder.build_unchecked() }
    420
    22
        }
    421
    }
    422
    423
    impl<'a> IntoIterator for &'a BooleanArray {
    424
        type Item = Option<bool>;
    425
        type IntoIter = BooleanIter<'a>;
    426
    427
    0
        fn into_iter(self) -> Self::IntoIter {
    428
    0
            BooleanIter::<'a>::new(self)
    429
    0
        }
    430
    }
    431
    432
    impl<'a> BooleanArray {
    433
        /// constructs a new iterator
    434
    768
        pub fn iter(&'a self) -> BooleanIter<'a> {
    435
    768
            BooleanIter::<'a>::new(self)
    436
    768
        }
    437
    }
    438
    439
    /// An optional boolean value
    440
    ///
    441
    /// This struct is used as an adapter when creating `BooleanArray` from an iterator.
    442
    /// `FromIterator` for `BooleanArray` takes an iterator where the elements can be `into`
    443
    /// this struct. So once implementing `From` or `Into` trait for a type, an iterator of
    444
    /// the type can be collected to `BooleanArray`.
    445
    ///
    446
    /// See also [NativeAdapter](crate::array::NativeAdapter).
    447
    #[derive(Debug)]
    448
    struct BooleanAdapter {
    449
        /// Corresponding Rust native type if available
    450
        pub native: Option<bool>,
    451
    }
    452
    453
    impl From<bool> for BooleanAdapter {
    454
    14
        fn from(value: bool) -> Self {
    455
    14
            BooleanAdapter {
    456
    14
                native: Some(value),
    457
    14
            }
    458
    14
        }
    459
    }
    460
    461
    impl From<&bool> for BooleanAdapter {
    462
    0
        fn from(value: &bool) -> Self {
    463
    0
            BooleanAdapter {
    464
    0
                native: Some(*value),
    465
    0
            }
    466
    0
        }
    467
    }
    468
    469
    impl From<Option<bool>> for BooleanAdapter {
    470
    647k
        fn from(value: Option<bool>) -> Self {
    471
    647k
            BooleanAdapter { native: value }
    472
    647k
        }
    473
    }
    474
    475
    impl From<&Option<bool>> for BooleanAdapter {
    476
    138
        fn from(value: &Option<bool>) -> Self {
    477
    138
            BooleanAdapter { native: *value }
    478
    138
        }
    479
    }
    480
    481
    impl<Ptr: Into<BooleanAdapter>> FromIterator<Ptr> for BooleanArray {
    482
    939
        fn from_iter<I: IntoIterator<Item = Ptr>>(iter: I) -> Self {
    483
    939
            let iter = iter.into_iter();
    484
    939
            let capacity = match iter.size_hint() {
    485
    939
                (lower, Some(upper)) if lower == upper => lower,
    486
    0
                _ => 0,
    487
            };
    488
    939
            let mut builder = BooleanBuilder::with_capacity(capacity);
    489
    324k
            builder939.extend939(iter939.map939(|item| item.into().native));
    490
    939
            builder.finish()
    491
    939
        }
    492
    }
    493
    494
    impl BooleanArray {
    495
        /// Creates a [`BooleanArray`] from an iterator of trusted length.
    496
        ///
    497
        /// # Safety
    498
        ///
    499
        /// The iterator must be [`TrustedLen`](https://doc.rust-lang.org/std/iter/trait.TrustedLen.html).
    500
        /// I.e. that `size_hint().1` correctly reports its length. Note that this is a stronger
    501
        /// guarantee that `ExactSizeIterator` provides which could still report a wrong length.
    502
        ///
    503
        /// # Panics
    504
        ///
    505
        /// Panics if the iterator does not report an upper bound on `size_hint()`.
    506
        #[inline]
    507
        #[allow(
    508
            private_bounds,
    509
            reason = "We will expose BooleanAdapter if there is a need"
    510
        )]
    511
    939
        pub unsafe fn from_trusted_len_iter<I, P>(iter: I) -> Self
    512
    939
        where
    513
    939
            P: Into<BooleanAdapter>,
    514
    939
            I: ExactSizeIterator<Item = P>,
    515
        {
    516
    939
            let data_len = iter.len();
    517
    518
    939
            let num_bytes = bit_util::ceil(data_len, 8);
    519
    939
            let mut null_builder = MutableBuffer::from_len_zeroed(num_bytes);
    520
    939
            let mut val_builder = MutableBuffer::from_len_zeroed(num_bytes);
    521
    522
    939
            let data = val_builder.as_slice_mut();
    523
    524
    939
            let null_slice = null_builder.as_slice_mut();
    525
    324k
            iter939.enumerate939().for_each939(|(i, item)| {
    526
    324k
                if let Some(a293k) = item.into().native {
    527
                    unsafe {
    528
                        // SAFETY: There will be enough space in the buffers due to the trusted len size
    529
                        // hint
    530
    293k
                        bit_util::set_bit_raw(null_slice.as_mut_ptr(), i);
    531
    293k
                        if a {
    532
    38.2k
                            bit_util::set_bit_raw(data.as_mut_ptr(), i);
    533
    255k
                        }
    534
                    }
    535
    30.7k
                }
    536
    324k
            });
    537
    538
    939
            let data = unsafe {
    539
    939
                ArrayData::new_unchecked(
    540
    939
                    DataType::Boolean,
    541
    939
                    data_len,
    542
    939
                    None,
    543
    939
                    Some(null_builder.into()),
    544
                    0,
    545
    939
                    vec![val_builder.into()],
    546
    939
                    vec![],
    547
                )
    548
            };
    549
    939
            BooleanArray::from(data)
    550
    939
        }
    551
    }
    552
    553
    impl From<BooleanBuffer> for BooleanArray {
    554
    4
        fn from(values: BooleanBuffer) -> Self {
    555
    4
            Self {
    556
    4
                values,
    557
    4
                nulls: None,
    558
    4
            }
    559
    4
        }
    560
    }
    561
    562
    #[cfg(test)]
    563
    mod tests {
    564
        use super::*;
    565
        use arrow_buffer::Buffer;
    566
        use rand::{Rng, rng};
    567
    568
        #[test]
    569
        fn test_boolean_fmt_debug() {
    570
            let arr = BooleanArray::from(vec![true, false, false]);
    571
            assert_eq!(
    572
                "BooleanArray\n[\n  true,\n  false,\n  false,\n]",
    573
                format!("{arr:?}")
    574
            );
    575
        }
    576
    577
        #[test]
    578
        fn test_boolean_with_null_fmt_debug() {
    579
            let mut builder = BooleanArray::builder(3);
    580
            builder.append_value(true);
    581
            builder.append_null();
    582
            builder.append_value(false);
    583
            let arr = builder.finish();
    584
            assert_eq!(
    585
                "BooleanArray\n[\n  true,\n  null,\n  false,\n]",
    586
                format!("{arr:?}")
    587
            );
    588
        }
    589
    590
        #[test]
    591
        fn test_boolean_array_from_vec() {
    592
            let buf = Buffer::from([10_u8]);
    593
            let arr = BooleanArray::from(vec![false, true, false, true]);
    594
            assert_eq!(&buf, arr.values().inner());
    595
            assert_eq!(4, arr.len());
    596
            assert_eq!(0, arr.offset());
    597
            assert_eq!(0, arr.null_count());
    598
            for i in 0..4 {
    599
                assert!(!arr.is_null(i));
    600
                assert!(arr.is_valid(i));
    601
                assert_eq!(i == 1 || i == 3, arr.value(i), "failed at {i}")
    602
            }
    603
        }
    604
    605
        #[test]
    606
        fn test_boolean_array_from_vec_option() {
    607
            let buf = Buffer::from([10_u8]);
    608
            let arr = BooleanArray::from(vec![Some(false), Some(true), None, Some(true)]);
    609
            assert_eq!(&buf, arr.values().inner());
    610
            assert_eq!(4, arr.len());
    611
            assert_eq!(0, arr.offset());
    612
            assert_eq!(1, arr.null_count());
    613
            for i in 0..4 {
    614
                if i == 2 {
    615
                    assert!(arr.is_null(i));
    616
                    assert!(!arr.is_valid(i));
    617
                } else {
    618
                    assert!(!arr.is_null(i));
    619
                    assert!(arr.is_valid(i));
    620
                    assert_eq!(i == 1 || i == 3, arr.value(i), "failed at {i}")
    621
                }
    622
            }
    623
        }
    624
    625
        #[test]
    626
        fn test_boolean_array_from_packed() {
    627
            let v = [1_u8, 2_u8, 3_u8];
    628
            let arr = BooleanArray::new_from_packed(v, 0, 24);
    629
            assert_eq!(24, arr.len());
    630
            assert_eq!(0, arr.offset());
    631
            assert_eq!(0, arr.null_count());
    632
            assert!(arr.nulls.is_none());
    633
            for i in 0..24 {
    634
                assert!(!arr.is_null(i));
    635
                assert!(arr.is_valid(i));
    636
                assert_eq!(
    637
                    i == 0 || i == 9 || i == 16 || i == 17,
    638
                    arr.value(i),
    639
                    "failed t {i}"
    640
                )
    641
            }
    642
        }
    643
    644
        #[test]
    645
        fn test_boolean_array_from_slice_u8() {
    646
            let v: Vec<u8> = vec![1, 2, 3];
    647
            let slice = &v[..];
    648
            let arr = BooleanArray::new_from_u8(slice);
    649
            assert_eq!(24, arr.len());
    650
            assert_eq!(0, arr.offset());
    651
            assert_eq!(0, arr.null_count());
    652
            assert!(arr.nulls().is_none());
    653
            for i in 0..24 {
    654
                assert!(!arr.is_null(i));
    655
                assert!(arr.is_valid(i));
    656
                assert_eq!(
    657
                    i == 0 || i == 9 || i == 16 || i == 17,
    658
                    arr.value(i),
    659
                    "failed t {i}"
    660
                )
    661
            }
    662
        }
    663
    664
        #[test]
    665
        fn test_boolean_array_from_iter() {
    666
            let v = vec![Some(false), Some(true), Some(false), Some(true)];
    667
            let arr = v.into_iter().collect::<BooleanArray>();
    668
            assert_eq!(4, arr.len());
    669
            assert_eq!(0, arr.offset());
    670
            assert_eq!(0, arr.null_count());
    671
            assert!(arr.nulls().is_none());
    672
            for i in 0..3 {
    673
                assert!(!arr.is_null(i));
    674
                assert!(arr.is_valid(i));
    675
                assert_eq!(i == 1 || i == 3, arr.value(i), "failed at {i}")
    676
            }
    677
        }
    678
    679
        #[test]
    680
        fn test_boolean_array_from_non_nullable_iter() {
    681
            let v = vec![true, false, true];
    682
            let arr = v.into_iter().collect::<BooleanArray>();
    683
            assert_eq!(3, arr.len());
    684
            assert_eq!(0, arr.offset());
    685
            assert_eq!(0, arr.null_count());
    686
            assert!(arr.nulls().is_none());
    687
    688
            assert!(arr.value(0));
    689
            assert!(!arr.value(1));
    690
            assert!(arr.value(2));
    691
        }
    692
    693
        #[test]
    694
        fn test_boolean_array_from_nullable_iter() {
    695
            let v = vec![Some(true), None, Some(false), None];
    696
            let arr = v.into_iter().collect::<BooleanArray>();
    697
            assert_eq!(4, arr.len());
    698
            assert_eq!(0, arr.offset());
    699
            assert_eq!(2, arr.null_count());
    700
            assert!(arr.nulls().is_some());
    701
    702
            assert!(arr.is_valid(0));
    703
            assert!(arr.is_null(1));
    704
            assert!(arr.is_valid(2));
    705
            assert!(arr.is_null(3));
    706
    707
            assert!(arr.value(0));
    708
            assert!(!arr.value(2));
    709
        }
    710
    711
        #[test]
    712
        fn test_boolean_array_from_nullable_trusted_len_iter() {
    713
            // Should exhibit the same behavior as `from_iter`, which is tested above.
    714
            let v = vec![Some(true), None, Some(false), None];
    715
            let expected = v.clone().into_iter().collect::<BooleanArray>();
    716
            let actual = unsafe {
    717
                // SAFETY: `v` has trusted length
    718
                BooleanArray::from_trusted_len_iter(v.into_iter())
    719
            };
    720
            assert_eq!(expected, actual);
    721
        }
    722
    723
        #[test]
    724
        fn test_boolean_array_from_iter_with_larger_upper_bound() {
    725
            // See https://github.com/apache/arrow-rs/issues/8505
    726
            // This returns an upper size hint of 4
    727
            let iterator = vec![Some(true), None, Some(false), None]
    728
                .into_iter()
    729
                .filter(Option::is_some);
    730
            let arr = iterator.collect::<BooleanArray>();
    731
            assert_eq!(2, arr.len());
    732
        }
    733
    734
        #[test]
    735
        fn test_boolean_array_builder() {
    736
            // Test building a boolean array with ArrayData builder and offset
    737
            // 000011011
    738
            let buf = Buffer::from([27_u8]);
    739
            let buf2 = buf.clone();
    740
            let data = ArrayData::builder(DataType::Boolean)
    741
                .len(5)
    742
                .offset(2)
    743
                .add_buffer(buf)
    744
                .build()
    745
                .unwrap();
    746
            let arr = BooleanArray::from(data);
    747
            assert_eq!(&buf2, arr.values().inner());
    748
            assert_eq!(5, arr.len());
    749
            assert_eq!(2, arr.offset());
    750
            assert_eq!(0, arr.null_count());
    751
            for i in 0..3 {
    752
                assert_eq!(i != 0, arr.value(i), "failed at {i}");
    753
            }
    754
        }
    755
    756
        #[test]
    757
        #[should_panic(
    758
            expected = "Trying to access an element at index 4 from a BooleanArray of length 3"
    759
        )]
    760
        fn test_fixed_size_binary_array_get_value_index_out_of_bound() {
    761
            let v = vec![Some(true), None, Some(false)];
    762
            let array = v.into_iter().collect::<BooleanArray>();
    763
    764
            array.value(4);
    765
        }
    766
    767
        #[test]
    768
        #[should_panic(expected = "BooleanArray data should contain a single buffer only \
    769
                                   (values buffer)")]
    770
        // Different error messages, so skip for now
    771
        // https://github.com/apache/arrow-rs/issues/1545
    772
        #[cfg(not(feature = "force_validate"))]
    773
        fn test_boolean_array_invalid_buffer_len() {
    774
            let data = unsafe {
    775
                ArrayData::builder(DataType::Boolean)
    776
                    .len(5)
    777
                    .build_unchecked()
    778
            };
    779
            drop(BooleanArray::from(data));
    780
        }
    781
    782
        #[test]
    783
        #[should_panic(expected = "BooleanArray expected ArrayData with type Boolean got Int32")]
    784
        fn test_from_array_data_validation() {
    785
            let _ = BooleanArray::from(ArrayData::new_empty(&DataType::Int32));
    786
        }
    787
    788
        #[test]
    789
        #[cfg_attr(miri, ignore)] // Takes too long
    790
        fn test_true_false_count() {
    791
            let mut rng = rng();
    792
    793
            for _ in 0..10 {
    794
                // No nulls
    795
                let d: Vec<_> = (0..2000).map(|_| rng.random_bool(0.5)).collect();
    796
                let b = BooleanArray::from(d.clone());
    797
    798
                let expected_true = d.iter().filter(|x| **x).count();
    799
                assert_eq!(b.true_count(), expected_true);
    800
                assert_eq!(b.false_count(), d.len() - expected_true);
    801
    802
                // With nulls
    803
                let d: Vec<_> = (0..2000)
    804
                    .map(|_| rng.random_bool(0.5).then(|| rng.random_bool(0.5)))
    805
                    .collect();
    806
                let b = BooleanArray::from(d.clone());
    807
    808
                let expected_true = d.iter().filter(|x| matches!(x, Some(true))).count();
    809
                assert_eq!(b.true_count(), expected_true);
    810
    811
                let expected_false = d.iter().filter(|x| matches!(x, Some(false))).count();
    812
                assert_eq!(b.false_count(), expected_false);
    813
            }
    814
        }
    815
    816
        #[test]
    817
        fn test_into_parts() {
    818
            let boolean_array = [Some(true), None, Some(false)]
    819
                .into_iter()
    820
                .collect::<BooleanArray>();
    821
            let (values, nulls) = boolean_array.into_parts();
    822
            assert_eq!(values.values(), &[0b0000_0001]);
    823
            assert!(nulls.is_some());
    824
            assert_eq!(nulls.unwrap().buffer().as_slice(), &[0b0000_0101]);
    825
    826
            let boolean_array =
    827
                BooleanArray::from(vec![false, false, false, false, false, false, false, true]);
    828
            let (values, nulls) = boolean_array.into_parts();
    829
            assert_eq!(values.values(), &[0b1000_0000]);
    830
            assert!(nulls.is_none());
    831
        }
    832
    }