This is an automated email from the ASF dual-hosted git repository.

tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/master by this push:
     new 91b2d7e66 Add ArrayAccessor trait, remove duplication in array 
iterators (#1948) (#2133)
91b2d7e66 is described below

commit 91b2d7e66b066d54035774625b29ff226c755172
Author: Raphael Taylor-Davies <[email protected]>
AuthorDate: Fri Jul 22 15:20:49 2022 -0400

    Add ArrayAccessor trait, remove duplication in array iterators (#1948) 
(#2133)
    
    * Add ArrayAccessor trait (#1948)
    
    * Re-export ArrayAccessor
    
    * Add docs
---
 arrow/src/array/array.rs           |  79 +++++++++
 arrow/src/array/array_binary.rs    |  15 ++
 arrow/src/array/array_boolean.rs   |  13 ++
 arrow/src/array/array_list.rs      |  27 ++-
 arrow/src/array/array_primitive.rs |  13 ++
 arrow/src/array/array_string.rs    |  15 ++
 arrow/src/array/equal_json.rs      |  10 ++
 arrow/src/array/iterator.rs        | 331 +++----------------------------------
 arrow/src/array/mod.rs             |   1 +
 9 files changed, 193 insertions(+), 311 deletions(-)

diff --git a/arrow/src/array/array.rs b/arrow/src/array/array.rs
index 3d8fdd70b..5c5231296 100644
--- a/arrow/src/array/array.rs
+++ b/arrow/src/array/array.rs
@@ -297,6 +297,85 @@ impl Array for ArrayRef {
     }
 }
 
+impl<'a, T: Array> Array for &'a T {
+    fn as_any(&self) -> &dyn Any {
+        T::as_any(self)
+    }
+
+    fn data(&self) -> &ArrayData {
+        T::data(self)
+    }
+
+    fn into_data(self) -> ArrayData {
+        self.data().clone()
+    }
+
+    fn data_ref(&self) -> &ArrayData {
+        T::data_ref(self)
+    }
+
+    fn data_type(&self) -> &DataType {
+        T::data_type(self)
+    }
+
+    fn slice(&self, offset: usize, length: usize) -> ArrayRef {
+        T::slice(self, offset, length)
+    }
+
+    fn len(&self) -> usize {
+        T::len(self)
+    }
+
+    fn is_empty(&self) -> bool {
+        T::is_empty(self)
+    }
+
+    fn offset(&self) -> usize {
+        T::offset(self)
+    }
+
+    fn is_null(&self, index: usize) -> bool {
+        T::is_null(self, index)
+    }
+
+    fn is_valid(&self, index: usize) -> bool {
+        T::is_valid(self, index)
+    }
+
+    fn null_count(&self) -> usize {
+        T::null_count(self)
+    }
+
+    fn get_buffer_memory_size(&self) -> usize {
+        T::get_buffer_memory_size(self)
+    }
+
+    fn get_array_memory_size(&self) -> usize {
+        T::get_array_memory_size(self)
+    }
+
+    fn to_raw(
+        &self,
+    ) -> Result<(*const ffi::FFI_ArrowArray, *const ffi::FFI_ArrowSchema)> {
+        T::to_raw(self)
+    }
+}
+
+/// A generic trait for accessing the values of an [`Array`]
+pub trait ArrayAccessor: Array {
+    type Item: Send + Sync;
+
+    /// Returns the element at index `i`
+    /// # Panics
+    /// Panics if the value is outside the bounds of the array
+    fn value(&self, index: usize) -> Self::Item;
+
+    /// Returns the element at index `i`
+    /// # Safety
+    /// Caller is responsible for ensuring that the index is within the bounds 
of the array
+    unsafe fn value_unchecked(&self, index: usize) -> Self::Item;
+}
+
 /// Constructs an array using the input `data`.
 /// Returns a reference-counted `Array` instance.
 pub fn make_array(data: ArrayData) -> ArrayRef {
diff --git a/arrow/src/array/array_binary.rs b/arrow/src/array/array_binary.rs
index d9cad1cce..b01696b03 100644
--- a/arrow/src/array/array_binary.rs
+++ b/arrow/src/array/array_binary.rs
@@ -23,6 +23,7 @@ use super::{
     array::print_long_array, raw_pointer::RawPtrBox, Array, ArrayData,
     FixedSizeListArray, GenericBinaryIter, GenericListArray, OffsetSizeTrait,
 };
+use crate::array::array::ArrayAccessor;
 pub use crate::array::DecimalIter;
 use crate::buffer::Buffer;
 use crate::error::{ArrowError, Result};
@@ -245,6 +246,20 @@ impl<OffsetSize: OffsetSizeTrait> Array for 
GenericBinaryArray<OffsetSize> {
     }
 }
 
+impl<'a, OffsetSize: OffsetSizeTrait> ArrayAccessor
+    for &'a GenericBinaryArray<OffsetSize>
+{
+    type Item = &'a [u8];
+
+    fn value(&self, index: usize) -> Self::Item {
+        GenericBinaryArray::value(self, index)
+    }
+
+    unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
+        GenericBinaryArray::value_unchecked(self, index)
+    }
+}
+
 impl<OffsetSize: OffsetSizeTrait> From<ArrayData> for 
GenericBinaryArray<OffsetSize> {
     fn from(data: ArrayData) -> Self {
         assert_eq!(
diff --git a/arrow/src/array/array_boolean.rs b/arrow/src/array/array_boolean.rs
index 6e11ff8cb..5d1e20705 100644
--- a/arrow/src/array/array_boolean.rs
+++ b/arrow/src/array/array_boolean.rs
@@ -15,6 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use crate::array::array::ArrayAccessor;
 use std::borrow::Borrow;
 use std::convert::From;
 use std::iter::{FromIterator, IntoIterator};
@@ -157,6 +158,18 @@ impl Array for BooleanArray {
     }
 }
 
+impl<'a> ArrayAccessor for &'a BooleanArray {
+    type Item = bool;
+
+    fn value(&self, index: usize) -> Self::Item {
+        BooleanArray::value(self, index)
+    }
+
+    unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
+        BooleanArray::value_unchecked(self, index)
+    }
+}
+
 impl From<Vec<bool>> for BooleanArray {
     fn from(data: Vec<bool>) -> Self {
         let mut mut_buf = MutableBuffer::new_null(data.len());
diff --git a/arrow/src/array/array_list.rs b/arrow/src/array/array_list.rs
index ac37754e9..22aa81ba7 100644
--- a/arrow/src/array/array_list.rs
+++ b/arrow/src/array/array_list.rs
@@ -24,6 +24,7 @@ use super::{
     array::print_long_array, make_array, raw_pointer::RawPtrBox, Array, 
ArrayData,
     ArrayRef, BooleanBufferBuilder, GenericListArrayIter, PrimitiveArray,
 };
+use crate::array::array::ArrayAccessor;
 use crate::{
     buffer::MutableBuffer,
     datatypes::{ArrowNativeType, ArrowPrimitiveType, DataType, Field},
@@ -245,7 +246,7 @@ impl<OffsetSize: OffsetSizeTrait> 
GenericListArray<OffsetSize> {
     }
 }
 
-impl<OffsetSize: 'static + OffsetSizeTrait> Array for 
GenericListArray<OffsetSize> {
+impl<OffsetSize: OffsetSizeTrait> Array for GenericListArray<OffsetSize> {
     fn as_any(&self) -> &dyn Any {
         self
     }
@@ -259,6 +260,18 @@ impl<OffsetSize: 'static + OffsetSizeTrait> Array for 
GenericListArray<OffsetSiz
     }
 }
 
+impl<'a, OffsetSize: OffsetSizeTrait> ArrayAccessor for &'a 
GenericListArray<OffsetSize> {
+    type Item = ArrayRef;
+
+    fn value(&self, index: usize) -> Self::Item {
+        GenericListArray::value(self, index)
+    }
+
+    unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
+        GenericListArray::value(self, index)
+    }
+}
+
 impl<OffsetSize: OffsetSizeTrait> fmt::Debug for GenericListArray<OffsetSize> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let prefix = if OffsetSize::IS_LARGE { "Large" } else { "" };
@@ -466,6 +479,18 @@ impl Array for FixedSizeListArray {
     }
 }
 
+impl ArrayAccessor for FixedSizeListArray {
+    type Item = ArrayRef;
+
+    fn value(&self, index: usize) -> Self::Item {
+        FixedSizeListArray::value(self, index)
+    }
+
+    unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
+        FixedSizeListArray::value(self, index)
+    }
+}
+
 impl fmt::Debug for FixedSizeListArray {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "FixedSizeListArray<{}>\n[\n", self.value_length())?;
diff --git a/arrow/src/array/array_primitive.rs 
b/arrow/src/array/array_primitive.rs
index 4ab8d4f46..eb731a2b2 100644
--- a/arrow/src/array/array_primitive.rs
+++ b/arrow/src/array/array_primitive.rs
@@ -33,6 +33,7 @@ use crate::{
     util::trusted_len_unzip,
 };
 
+use crate::array::array::ArrayAccessor;
 use half::f16;
 
 /// Array whose elements are of primitive types.
@@ -188,6 +189,18 @@ impl<T: ArrowPrimitiveType> Array for PrimitiveArray<T> {
     }
 }
 
+impl<'a, T: ArrowPrimitiveType> ArrayAccessor for &'a PrimitiveArray<T> {
+    type Item = T::Native;
+
+    fn value(&self, index: usize) -> Self::Item {
+        PrimitiveArray::value(self, index)
+    }
+
+    unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
+        PrimitiveArray::value_unchecked(self, index)
+    }
+}
+
 fn as_datetime<T: ArrowPrimitiveType>(v: i64) -> Option<NaiveDateTime> {
     match T::DATA_TYPE {
         DataType::Date32 => Some(temporal_conversions::date32_to_datetime(v as 
i32)),
diff --git a/arrow/src/array/array_string.rs b/arrow/src/array/array_string.rs
index 85cb346a7..df858d858 100644
--- a/arrow/src/array/array_string.rs
+++ b/arrow/src/array/array_string.rs
@@ -23,6 +23,7 @@ use super::{
     array::print_long_array, raw_pointer::RawPtrBox, Array, ArrayData, 
GenericListArray,
     GenericStringIter, OffsetSizeTrait,
 };
+use crate::array::array::ArrayAccessor;
 use crate::buffer::Buffer;
 use crate::util::bit_util;
 use crate::{buffer::MutableBuffer, datatypes::DataType};
@@ -298,6 +299,20 @@ impl<OffsetSize: OffsetSizeTrait> Array for 
GenericStringArray<OffsetSize> {
     }
 }
 
+impl<'a, OffsetSize: OffsetSizeTrait> ArrayAccessor
+    for &'a GenericStringArray<OffsetSize>
+{
+    type Item = &'a str;
+
+    fn value(&self, index: usize) -> Self::Item {
+        GenericStringArray::value(self, index)
+    }
+
+    unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
+        GenericStringArray::value_unchecked(self, index)
+    }
+}
+
 impl<OffsetSize: OffsetSizeTrait> From<ArrayData> for 
GenericStringArray<OffsetSize> {
     fn from(data: ArrayData) -> Self {
         assert_eq!(
diff --git a/arrow/src/array/equal_json.rs b/arrow/src/array/equal_json.rs
index 30d9c8f84..e7d14aae8 100644
--- a/arrow/src/array/equal_json.rs
+++ b/arrow/src/array/equal_json.rs
@@ -37,6 +37,16 @@ pub trait JsonEqual {
     }
 }
 
+impl<'a, T: JsonEqual> JsonEqual for &'a T {
+    fn equals_json(&self, json: &[&Value]) -> bool {
+        T::equals_json(self, json)
+    }
+
+    fn equals_json_values(&self, json: &[Value]) -> bool {
+        T::equals_json_values(self, json)
+    }
+}
+
 /// Implement array equals for numeric type
 impl<T: ArrowPrimitiveType> JsonEqual for PrimitiveArray<T> {
     fn equals_json(&self, json: &[&Value]) -> bool {
diff --git a/arrow/src/array/iterator.rs b/arrow/src/array/iterator.rs
index 8e45de286..a4853d7d7 100644
--- a/arrow/src/array/iterator.rs
+++ b/arrow/src/array/iterator.rs
@@ -15,36 +15,37 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use crate::array::array::ArrayAccessor;
 use crate::array::BasicDecimalArray;
-use crate::datatypes::ArrowPrimitiveType;
 
 use super::{
-    Array, ArrayRef, BooleanArray, Decimal128Array, GenericBinaryArray, 
GenericListArray,
-    GenericStringArray, OffsetSizeTrait, PrimitiveArray,
+    Array, BooleanArray, Decimal128Array, GenericBinaryArray, GenericListArray,
+    GenericStringArray, PrimitiveArray,
 };
 
-/// an iterator that returns Some(T) or None, that can be used on any 
PrimitiveArray
+/// an iterator that returns Some(T) or None, that can be used on any 
[`ArrayAccessor`]
 // Note: This implementation is based on std's [Vec]s' [IntoIter].
 #[derive(Debug)]
-pub struct PrimitiveIter<'a, T: ArrowPrimitiveType> {
-    array: &'a PrimitiveArray<T>,
+pub struct ArrayIter<T: ArrayAccessor> {
+    array: T,
     current: usize,
     current_end: usize,
 }
 
-impl<'a, T: ArrowPrimitiveType> PrimitiveIter<'a, T> {
+impl<T: ArrayAccessor> ArrayIter<T> {
     /// create a new iterator
-    pub fn new(array: &'a PrimitiveArray<T>) -> Self {
-        PrimitiveIter::<T> {
+    pub fn new(array: T) -> Self {
+        let len = array.len();
+        ArrayIter {
             array,
             current: 0,
-            current_end: array.len(),
+            current_end: len,
         }
     }
 }
 
-impl<'a, T: ArrowPrimitiveType> std::iter::Iterator for PrimitiveIter<'a, T> {
-    type Item = Option<T::Native>;
+impl<T: ArrayAccessor> Iterator for ArrayIter<T> {
+    type Item = Option<T::Item>;
 
     #[inline]
     fn next(&mut self) -> Option<Self::Item> {
@@ -73,7 +74,7 @@ impl<'a, T: ArrowPrimitiveType> std::iter::Iterator for 
PrimitiveIter<'a, T> {
     }
 }
 
-impl<'a, T: ArrowPrimitiveType> std::iter::DoubleEndedIterator for 
PrimitiveIter<'a, T> {
+impl<T: ArrayAccessor> DoubleEndedIterator for ArrayIter<T> {
     fn next_back(&mut self) -> Option<Self::Item> {
         if self.current_end == self.current {
             None
@@ -94,304 +95,14 @@ impl<'a, T: ArrowPrimitiveType> 
std::iter::DoubleEndedIterator for PrimitiveIter
 }
 
 /// all arrays have known size.
-impl<'a, T: ArrowPrimitiveType> std::iter::ExactSizeIterator for 
PrimitiveIter<'a, T> {}
-
-/// an iterator that returns Some(bool) or None.
-// Note: This implementation is based on std's [Vec]s' [IntoIter].
-#[derive(Debug)]
-pub struct BooleanIter<'a> {
-    array: &'a BooleanArray,
-    current: usize,
-    current_end: usize,
-}
-
-impl<'a> BooleanIter<'a> {
-    /// create a new iterator
-    pub fn new(array: &'a BooleanArray) -> Self {
-        BooleanIter {
-            array,
-            current: 0,
-            current_end: array.len(),
-        }
-    }
-}
-
-impl<'a> std::iter::Iterator for BooleanIter<'a> {
-    type Item = Option<bool>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        if self.current == self.current_end {
-            None
-        } else if self.array.is_null(self.current) {
-            self.current += 1;
-            Some(None)
-        } else {
-            let old = self.current;
-            self.current += 1;
-            // Safety:
-            // we just checked bounds in `self.current_end == self.current`
-            // this is safe on the premise that this struct is initialized with
-            // current = array.len()
-            // and that current_end is ever only decremented
-            unsafe { Some(Some(self.array.value_unchecked(old))) }
-        }
-    }
+impl<T: ArrayAccessor> ExactSizeIterator for ArrayIter<T> {}
 
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (
-            self.array.len() - self.current,
-            Some(self.array.len() - self.current),
-        )
-    }
-}
-
-impl<'a> std::iter::DoubleEndedIterator for BooleanIter<'a> {
-    fn next_back(&mut self) -> Option<Self::Item> {
-        if self.current_end == self.current {
-            None
-        } else {
-            self.current_end -= 1;
-            Some(if self.array.is_null(self.current_end) {
-                None
-            } else {
-                // Safety:
-                // we just checked bounds in `self.current_end == self.current`
-                // this is safe on the premise that this struct is initialized 
with
-                // current = array.len()
-                // and that current_end is ever only decremented
-                unsafe { Some(self.array.value_unchecked(self.current_end)) }
-            })
-        }
-    }
-}
-
-/// all arrays have known size.
-impl<'a> std::iter::ExactSizeIterator for BooleanIter<'a> {}
-
-/// an iterator that returns `Some(&str)` or `None`, for string arrays
-#[derive(Debug)]
-pub struct GenericStringIter<'a, T>
-where
-    T: OffsetSizeTrait,
-{
-    array: &'a GenericStringArray<T>,
-    current: usize,
-    current_end: usize,
-}
-
-impl<'a, T: OffsetSizeTrait> GenericStringIter<'a, T> {
-    /// create a new iterator
-    pub fn new(array: &'a GenericStringArray<T>) -> Self {
-        GenericStringIter::<T> {
-            array,
-            current: 0,
-            current_end: array.len(),
-        }
-    }
-}
-
-impl<'a, T: OffsetSizeTrait> std::iter::Iterator for GenericStringIter<'a, T> {
-    type Item = Option<&'a str>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let i = self.current;
-        if i >= self.current_end {
-            None
-        } else if self.array.is_null(i) {
-            self.current += 1;
-            Some(None)
-        } else {
-            self.current += 1;
-            // Safety:
-            // we just checked bounds in `self.current_end == self.current`
-            // this is safe on the premise that this struct is initialized with
-            // current = array.len()
-            // and that current_end is ever only decremented
-            unsafe { Some(Some(self.array.value_unchecked(i))) }
-        }
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (
-            self.current_end - self.current,
-            Some(self.current_end - self.current),
-        )
-    }
-}
-
-impl<'a, T: OffsetSizeTrait> std::iter::DoubleEndedIterator for 
GenericStringIter<'a, T> {
-    fn next_back(&mut self) -> Option<Self::Item> {
-        if self.current_end == self.current {
-            None
-        } else {
-            self.current_end -= 1;
-            Some(if self.array.is_null(self.current_end) {
-                None
-            } else {
-                // Safety:
-                // we just checked bounds in `self.current_end == self.current`
-                // this is safe on the premise that this struct is initialized 
with
-                // current = array.len()
-                // and that current_end is ever only decremented
-                unsafe { Some(self.array.value_unchecked(self.current_end)) }
-            })
-        }
-    }
-}
-
-/// all arrays have known size.
-impl<'a, T: OffsetSizeTrait> std::iter::ExactSizeIterator for 
GenericStringIter<'a, T> {}
-
-/// an iterator that returns `Some(&[u8])` or `None`, for binary arrays
-#[derive(Debug)]
-pub struct GenericBinaryIter<'a, T>
-where
-    T: OffsetSizeTrait,
-{
-    array: &'a GenericBinaryArray<T>,
-    current: usize,
-    current_end: usize,
-}
-
-impl<'a, T: OffsetSizeTrait> GenericBinaryIter<'a, T> {
-    /// create a new iterator
-    pub fn new(array: &'a GenericBinaryArray<T>) -> Self {
-        GenericBinaryIter::<T> {
-            array,
-            current: 0,
-            current_end: array.len(),
-        }
-    }
-}
-
-impl<'a, T: OffsetSizeTrait> std::iter::Iterator for GenericBinaryIter<'a, T> {
-    type Item = Option<&'a [u8]>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let i = self.current;
-        if i >= self.current_end {
-            None
-        } else if self.array.is_null(i) {
-            self.current += 1;
-            Some(None)
-        } else {
-            self.current += 1;
-            // Safety:
-            // we just checked bounds in `self.current_end == self.current`
-            // this is safe on the premise that this struct is initialized with
-            // current = array.len()
-            // and that current_end is ever only decremented
-            unsafe { Some(Some(self.array.value_unchecked(i))) }
-        }
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (
-            self.current_end - self.current,
-            Some(self.current_end - self.current),
-        )
-    }
-}
-
-impl<'a, T: OffsetSizeTrait> std::iter::DoubleEndedIterator for 
GenericBinaryIter<'a, T> {
-    fn next_back(&mut self) -> Option<Self::Item> {
-        if self.current_end == self.current {
-            None
-        } else {
-            self.current_end -= 1;
-            Some(if self.array.is_null(self.current_end) {
-                None
-            } else {
-                // Safety:
-                // we just checked bounds in `self.current_end == self.current`
-                // this is safe on the premise that this struct is initialized 
with
-                // current = array.len()
-                // and that current_end is ever only decremented
-                unsafe { Some(self.array.value_unchecked(self.current_end)) }
-            })
-        }
-    }
-}
-
-/// all arrays have known size.
-impl<'a, T: OffsetSizeTrait> std::iter::ExactSizeIterator for 
GenericBinaryIter<'a, T> {}
-
-#[derive(Debug)]
-pub struct GenericListArrayIter<'a, S>
-where
-    S: OffsetSizeTrait,
-{
-    array: &'a GenericListArray<S>,
-    current: usize,
-    current_end: usize,
-}
-
-impl<'a, S: OffsetSizeTrait> GenericListArrayIter<'a, S> {
-    pub fn new(array: &'a GenericListArray<S>) -> Self {
-        GenericListArrayIter::<S> {
-            array,
-            current: 0,
-            current_end: array.len(),
-        }
-    }
-}
-
-impl<'a, S: OffsetSizeTrait> std::iter::Iterator for GenericListArrayIter<'a, 
S> {
-    type Item = Option<ArrayRef>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let i = self.current;
-        if i >= self.current_end {
-            None
-        } else if self.array.is_null(i) {
-            self.current += 1;
-            Some(None)
-        } else {
-            self.current += 1;
-            // Safety:
-            // we just checked bounds in `self.current_end == self.current`
-            // this is safe on the premise that this struct is initialized with
-            // current = array.len()
-            // and that current_end is ever only decremented
-            unsafe { Some(Some(self.array.value_unchecked(i))) }
-        }
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (
-            self.current_end - self.current,
-            Some(self.current_end - self.current),
-        )
-    }
-}
-
-impl<'a, S: OffsetSizeTrait> std::iter::DoubleEndedIterator
-    for GenericListArrayIter<'a, S>
-{
-    fn next_back(&mut self) -> Option<Self::Item> {
-        if self.current_end == self.current {
-            None
-        } else {
-            self.current_end -= 1;
-            Some(if self.array.is_null(self.current_end) {
-                None
-            } else {
-                // Safety:
-                // we just checked bounds in `self.current_end == self.current`
-                // this is safe on the premise that this struct is initialized 
with
-                // current = array.len()
-                // and that current_end is ever only decremented
-                unsafe { Some(self.array.value_unchecked(self.current_end)) }
-            })
-        }
-    }
-}
-
-/// all arrays have known size.
-impl<'a, S: OffsetSizeTrait> std::iter::ExactSizeIterator
-    for GenericListArrayIter<'a, S>
-{
-}
+/// an iterator that returns Some(T) or None, that can be used on any 
PrimitiveArray
+pub type PrimitiveIter<'a, T> = ArrayIter<&'a PrimitiveArray<T>>;
+pub type BooleanIter<'a> = ArrayIter<&'a BooleanArray>;
+pub type GenericStringIter<'a, T> = ArrayIter<&'a GenericStringArray<T>>;
+pub type GenericBinaryIter<'a, T> = ArrayIter<&'a GenericBinaryArray<T>>;
+pub type GenericListArrayIter<'a, O> = ArrayIter<&'a GenericListArray<O>>;
 
 /// an iterator that returns `Some(i128)` or `None`, that can be used on a
 /// [`Decimal128Array`]
diff --git a/arrow/src/array/mod.rs b/arrow/src/array/mod.rs
index d805710cc..8acc33c7b 100644
--- a/arrow/src/array/mod.rs
+++ b/arrow/src/array/mod.rs
@@ -186,6 +186,7 @@ use crate::datatypes::*;
 // --------------------- Array & ArrayData ---------------------
 
 pub use self::array::Array;
+pub use self::array::ArrayAccessor;
 pub use self::array::ArrayRef;
 pub(crate) use self::data::layout;
 pub use self::data::ArrayData;

Reply via email to