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

alamb 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 258f828  Allow primitive array creation from iterators of 
PrimitiveTypes (as well as `Option`) (#1367)
258f828 is described below

commit 258f828f9fd5bdfb668cbab7005d6bff73184b8f
Author: Liang-Chi Hsieh <[email protected]>
AuthorDate: Thu Mar 3 06:04:43 2022 -0800

    Allow primitive array creation from iterators of PrimitiveTypes (as well as 
`Option`) (#1367)
    
    * More idiomatic primitive array creation
    
    * Use From instead for clippy
    
    * Rename to NativeAdapter and add document
---
 arrow/src/array/array_primitive.rs | 73 +++++++++++++++++++++++++++++++++++---
 1 file changed, 68 insertions(+), 5 deletions(-)

diff --git a/arrow/src/array/array_primitive.rs 
b/arrow/src/array/array_primitive.rs
index 79aa8e6..23e1c1f 100644
--- a/arrow/src/array/array_primitive.rs
+++ b/arrow/src/array/array_primitive.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use std::any::Any;
-use std::borrow::Borrow;
 use std::convert::From;
 use std::fmt;
 use std::iter::{FromIterator, IntoIterator};
@@ -34,6 +33,8 @@ use crate::{
     util::trusted_len_unzip,
 };
 
+use half::f16;
+
 /// Array whose elements are of primitive types.
 ///
 /// # Example: From an iterator of values
@@ -340,8 +341,57 @@ impl<'a, T: ArrowPrimitiveType> PrimitiveArray<T> {
     }
 }
 
-impl<T: ArrowPrimitiveType, Ptr: Borrow<Option<<T as 
ArrowPrimitiveType>::Native>>>
-    FromIterator<Ptr> for PrimitiveArray<T>
+/// This struct is used as an adapter when creating `PrimitiveArray` from an 
iterator.
+/// `FromIterator` for `PrimitiveArray` takes an iterator where the elements 
can be `into`
+/// this struct. So once implementing `From` or `Into` trait for a type, an 
iterator of
+/// the type can be collected to `PrimitiveArray`.
+#[derive(Debug)]
+pub struct NativeAdapter<T: ArrowPrimitiveType> {
+    pub native: Option<T::Native>,
+}
+
+macro_rules! def_from_for_primitive {
+    ( $ty:ident, $tt:tt) => {
+        impl From<$tt> for NativeAdapter<$ty> {
+            fn from(value: $tt) -> Self {
+                NativeAdapter {
+                    native: Some(value),
+                }
+            }
+        }
+    };
+}
+
+def_from_for_primitive!(Int8Type, i8);
+def_from_for_primitive!(Int16Type, i16);
+def_from_for_primitive!(Int32Type, i32);
+def_from_for_primitive!(Int64Type, i64);
+def_from_for_primitive!(UInt8Type, u8);
+def_from_for_primitive!(UInt16Type, u16);
+def_from_for_primitive!(UInt32Type, u32);
+def_from_for_primitive!(UInt64Type, u64);
+def_from_for_primitive!(Float16Type, f16);
+def_from_for_primitive!(Float32Type, f32);
+def_from_for_primitive!(Float64Type, f64);
+
+impl<T: ArrowPrimitiveType> From<Option<<T as ArrowPrimitiveType>::Native>>
+    for NativeAdapter<T>
+{
+    fn from(value: Option<<T as ArrowPrimitiveType>::Native>) -> Self {
+        NativeAdapter { native: value }
+    }
+}
+
+impl<T: ArrowPrimitiveType> From<&Option<<T as ArrowPrimitiveType>::Native>>
+    for NativeAdapter<T>
+{
+    fn from(value: &Option<<T as ArrowPrimitiveType>::Native>) -> Self {
+        NativeAdapter { native: *value }
+    }
+}
+
+impl<'a, T: ArrowPrimitiveType, Ptr: Into<NativeAdapter<T>>> FromIterator<Ptr>
+    for PrimitiveArray<T>
 {
     fn from_iter<I: IntoIterator<Item = Ptr>>(iter: I) -> Self {
         let iter = iter.into_iter();
@@ -351,9 +401,9 @@ impl<T: ArrowPrimitiveType, Ptr: Borrow<Option<<T as 
ArrowPrimitiveType>::Native
 
         let buffer: Buffer = iter
             .map(|item| {
-                if let Some(a) = item.borrow() {
+                if let Some(a) = item.into().native {
                     null_buf.append(true);
-                    *a
+                    a
                 } else {
                     null_buf.append(false);
                     // this ensures that null items on the buffer are not 
arbitrary.
@@ -530,6 +580,7 @@ mod tests {
     use std::thread;
 
     use crate::buffer::Buffer;
+    use crate::compute::eq_dyn;
     use crate::datatypes::DataType;
 
     #[test]
@@ -998,4 +1049,16 @@ mod tests {
         assert!(ret.is_ok());
         assert_eq!(8, ret.ok().unwrap());
     }
+
+    #[test]
+    fn test_primitive_array_creation() {
+        let array1: Int8Array = [10_i8, 11, 12, 13, 14].into_iter().collect();
+        let array2: Int8Array = [10_i8, 11, 12, 13, 
14].into_iter().map(Some).collect();
+
+        let result = eq_dyn(&array1, &array2);
+        assert_eq!(
+            result.unwrap(),
+            BooleanArray::from(vec![true, true, true, true, true])
+        );
+    }
 }

Reply via email to