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

github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new 8f4bb0caa7 Move numeric and boolean cast helpers into a private 
submodule (#11076)
8f4bb0caa7 is described below

commit 8f4bb0caa723c9536e59669418d475a6b544d2e9
Author: Anand Hegde <[email protected]>
AuthorDate: Fri Oct 16 14:12:17 2026 +0000

    Move numeric and boolean cast helpers into a private submodule (#11076)
    
    # Which issue does this PR close?
    
    - Part of #11032.
    
    # Rationale for this change
    
    Continues splitting up `cast/mod.rs`.
    
    # What changes are included in this PR?
    
    Moves the numeric and boolean cast helpers into a new `cast/numeric.rs`.
    Code is unchanged apart from `pub(crate)` visibility.
    
    # Are these changes tested?
    
    Covered by existing tests.
    
    # Are there any significant user-facing changes?
    
    No. The public helpers are re-exported, so their paths are unchanged.
---
 arrow-cast/src/cast/mod.rs     | 186 ++------------------------------------
 arrow-cast/src/cast/numeric.rs | 200 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 206 insertions(+), 180 deletions(-)

diff --git a/arrow-cast/src/cast/mod.rs b/arrow-cast/src/cast/mod.rs
index 65bf6bbc8d..94de6548f4 100644
--- a/arrow-cast/src/cast/mod.rs
+++ b/arrow-cast/src/cast/mod.rs
@@ -42,6 +42,7 @@ mod decimal;
 mod dictionary;
 mod list;
 mod map;
+mod numeric;
 mod run_array;
 mod string;
 mod structs;
@@ -53,6 +54,10 @@ use crate::cast::decimal::*;
 use crate::cast::dictionary::*;
 use crate::cast::list::*;
 use crate::cast::map::*;
+pub(crate) use crate::cast::numeric::{
+    cast_bool_to_numeric, cast_numeric_arrays, cast_numeric_to_bool,
+};
+pub use crate::cast::numeric::{cast_num_to_bool, num_cast, 
single_bool_to_numeric};
 use crate::cast::run_array::*;
 use crate::cast::string::*;
 use crate::cast::structs::*;
@@ -2310,189 +2315,10 @@ where
     Ok(Arc::new(result))
 }
 
-/// Convert Array into a PrimitiveArray of type, and apply numeric cast
-fn cast_numeric_arrays<FROM, TO>(
-    from: &dyn Array,
-    cast_options: &CastOptions,
-) -> Result<ArrayRef, ArrowError>
-where
-    FROM: ArrowPrimitiveType,
-    TO: ArrowPrimitiveType,
-    FROM::Native: NumCast + NumericNative,
-    TO::Native: NumCast + NumericNative,
-{
-    let from = from.as_primitive::<FROM>();
-    let array: PrimitiveArray<TO> = if const {
-        is_infallible_numeric_cast(
-            <FROM::Native as NumericNative>::KIND,
-            <TO::Native as NumericNative>::KIND,
-        )
-    } {
-        // This cast cannot fail, so the fastest kernel, `unary`, can be used.
-        from.unary(|v| num_cast(v).expect("numeric cast is infallible"))
-    } else if cast_options.safe {
-        // If the value can't be cast to the `TO::Native`, return null
-        from.unary_opt(num_cast)
-    } else {
-        // If the value can't be cast to the `TO::Native`, return error
-        from.try_unary(|v| {
-            num_cast(v).ok_or_else(|| {
-                ArrowError::CastError(format!("Can't cast value {v:?} to type 
{}", TO::DATA_TYPE))
-            })
-        })?
-    };
-    Ok(Arc::new(array))
-}
-
-/// Properties of a numeric native type that decide whether [`num_cast`] to
-/// another numeric type can fail.
-#[derive(Clone, Copy)]
-struct NumericKind {
-    float: bool,
-    signed: bool,
-    bits: u32,
-}
-
-/// A native type with a [`NumericKind`].
-trait NumericNative {
-    const KIND: NumericKind;
-}
-
-macro_rules! numeric_native {
-    ($($t:ty => $float:literal, $signed:literal;)*) => {$(
-        impl NumericNative for $t {
-            const KIND: NumericKind = NumericKind {
-                float: $float,
-                signed: $signed,
-                bits: 8 * std::mem::size_of::<$t>() as u32,
-            };
-        }
-    )*};
-}
-
-numeric_native! {
-    u8 => false, false;
-    u16 => false, false;
-    u32 => false, false;
-    u64 => false, false;
-    i8 => false, true;
-    i16 => false, true;
-    i32 => false, true;
-    i64 => false, true;
-    half::f16 => true, true;
-    f32 => true, true;
-    f64 => true, true;
-}
-
-/// Returns true if [`num_cast`] succeeds for every value of `from` when 
casting
-/// to `to`: every cast to a float, and integer casts whose target holds every
-/// source value.
-///
-/// This must hold for every bit pattern of the source type, not only for the
-/// valid values of a particular array, because [`PrimitiveArray::unary`] 
applies
-/// the conversion to null slots as well, and their contents are arbitrary.
-const fn is_infallible_numeric_cast(from: NumericKind, to: NumericKind) -> 
bool {
-    if to.float {
-        true
-    } else if from.float {
-        false
-    } else if from.signed == to.signed {
-        to.bits >= from.bits
-    } else {
-        // Only an unsigned source fits a strictly wider signed target.
-        !from.signed && to.bits > from.bits
-    }
-}
-
-/// Natural cast between numeric types
-/// Return None if the input `value` can't be casted to type `O`.
-#[inline]
-pub fn num_cast<I, O>(value: I) -> Option<O>
-where
-    I: NumCast,
-    O: NumCast,
-{
-    num_traits::cast::cast::<I, O>(value)
-}
-
-/// Cast numeric types to Boolean
-///
-/// Any zero value returns `false` while non-zero returns `true`
-fn cast_numeric_to_bool<FROM>(from: &dyn Array) -> Result<ArrayRef, ArrowError>
-where
-    FROM: ArrowPrimitiveType,
-{
-    Ok(Arc::new(BooleanArray::from_unary(
-        from.as_primitive::<FROM>(),
-        cast_num_to_bool,
-    )))
-}
-
-/// Cast numeric types to boolean
-#[inline]
-pub fn cast_num_to_bool<I>(value: I) -> bool
-where
-    I: Default + PartialEq,
-{
-    value != I::default()
-}
-
-/// Cast Boolean types to numeric
-///
-/// `false` returns 0 while `true` returns 1
-fn cast_bool_to_numeric<TO>(
-    from: &dyn Array,
-    cast_options: &CastOptions,
-) -> Result<ArrayRef, ArrowError>
-where
-    TO: ArrowPrimitiveType,
-{
-    Ok(Arc::new(bool_to_numeric_cast::<TO>(
-        from.as_any().downcast_ref::<BooleanArray>().unwrap(),
-        cast_options,
-    )))
-}
-
-fn bool_to_numeric_cast<T>(from: &BooleanArray, _cast_options: &CastOptions) 
-> PrimitiveArray<T>
-where
-    T: ArrowPrimitiveType,
-{
-    let to_numeric = |bits: u64, i: usize| {
-        if bits & (1 << i) != 0 {
-            T::Native::ONE
-        } else {
-            T::Native::ZERO
-        }
-    };
-    // Unpack a 64-bit word at a time: the fixed-size inner loop helps the
-    // compiler vectorize the conversion.
-    let chunks = from.values().bit_chunks();
-    let mut values = Vec::with_capacity(from.len());
-    for bits in &chunks {
-        values.extend((0..64).map(|i| to_numeric(bits, i)));
-    }
-    let bits = chunks.remainder_bits();
-    values.extend((0..chunks.remainder_len()).map(|i| to_numeric(bits, i)));
-    PrimitiveArray::new(values.into(), from.nulls().cloned())
-}
-
-/// Cast single bool value to numeric value.
-#[inline]
-pub fn single_bool_to_numeric<O>(value: bool) -> Option<O>
-where
-    O: num_traits::NumCast + Default,
-{
-    if value {
-        // a workaround to cast a primitive to type O, infallible
-        num_traits::cast::cast(1)
-    } else {
-        Some(O::default())
-    }
-}
-
 #[cfg(test)]
 mod tests {
     use super::*;
+    use crate::cast::numeric::{NumericNative, is_infallible_numeric_cast};
     use crate::parse::parse_decimal;
     use DataType::*;
     use arrow_array::{Int64Array, RunArray, StringArray};
diff --git a/arrow-cast/src/cast/numeric.rs b/arrow-cast/src/cast/numeric.rs
new file mode 100644
index 0000000000..6a5cb0a4ab
--- /dev/null
+++ b/arrow-cast/src/cast/numeric.rs
@@ -0,0 +1,200 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+//! Cast support for numeric and boolean arrays.
+
+use crate::cast::*;
+
+/// Convert Array into a PrimitiveArray of type, and apply numeric cast
+pub(crate) fn cast_numeric_arrays<FROM, TO>(
+    from: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError>
+where
+    FROM: ArrowPrimitiveType,
+    TO: ArrowPrimitiveType,
+    FROM::Native: NumCast + NumericNative,
+    TO::Native: NumCast + NumericNative,
+{
+    let from = from.as_primitive::<FROM>();
+    let array: PrimitiveArray<TO> = if const {
+        is_infallible_numeric_cast(
+            <FROM::Native as NumericNative>::KIND,
+            <TO::Native as NumericNative>::KIND,
+        )
+    } {
+        // This cast cannot fail, so the fastest kernel, `unary`, can be used.
+        from.unary(|v| num_cast(v).expect("numeric cast is infallible"))
+    } else if cast_options.safe {
+        // If the value can't be cast to the `TO::Native`, return null
+        from.unary_opt(num_cast)
+    } else {
+        // If the value can't be cast to the `TO::Native`, return error
+        from.try_unary(|v| {
+            num_cast(v).ok_or_else(|| {
+                ArrowError::CastError(format!("Can't cast value {v:?} to type 
{}", TO::DATA_TYPE))
+            })
+        })?
+    };
+    Ok(Arc::new(array))
+}
+
+/// Properties of a numeric native type that decide whether [`num_cast`] to
+/// another numeric type can fail.
+#[derive(Clone, Copy)]
+pub(crate) struct NumericKind {
+    float: bool,
+    signed: bool,
+    bits: u32,
+}
+
+/// A native type with a [`NumericKind`].
+pub(crate) trait NumericNative {
+    const KIND: NumericKind;
+}
+
+macro_rules! numeric_native {
+    ($($t:ty => $float:literal, $signed:literal;)*) => {$(
+        impl NumericNative for $t {
+            const KIND: NumericKind = NumericKind {
+                float: $float,
+                signed: $signed,
+                bits: 8 * std::mem::size_of::<$t>() as u32,
+            };
+        }
+    )*};
+}
+
+numeric_native! {
+    u8 => false, false;
+    u16 => false, false;
+    u32 => false, false;
+    u64 => false, false;
+    i8 => false, true;
+    i16 => false, true;
+    i32 => false, true;
+    i64 => false, true;
+    half::f16 => true, true;
+    f32 => true, true;
+    f64 => true, true;
+}
+
+/// Returns true if [`num_cast`] succeeds for every value of `from` when 
casting
+/// to `to`: every cast to a float, and integer casts whose target holds every
+/// source value.
+///
+/// This must hold for every bit pattern of the source type, not only for the
+/// valid values of a particular array, because [`PrimitiveArray::unary`] 
applies
+/// the conversion to null slots as well, and their contents are arbitrary.
+pub(crate) const fn is_infallible_numeric_cast(from: NumericKind, to: 
NumericKind) -> bool {
+    if to.float {
+        true
+    } else if from.float {
+        false
+    } else if from.signed == to.signed {
+        to.bits >= from.bits
+    } else {
+        // Only an unsigned source fits a strictly wider signed target.
+        !from.signed && to.bits > from.bits
+    }
+}
+
+/// Natural cast between numeric types
+/// Return None if the input `value` can't be casted to type `O`.
+#[inline]
+pub fn num_cast<I, O>(value: I) -> Option<O>
+where
+    I: NumCast,
+    O: NumCast,
+{
+    num_traits::cast::cast::<I, O>(value)
+}
+
+/// Cast numeric types to Boolean
+///
+/// Any zero value returns `false` while non-zero returns `true`
+pub(crate) fn cast_numeric_to_bool<FROM>(from: &dyn Array) -> Result<ArrayRef, 
ArrowError>
+where
+    FROM: ArrowPrimitiveType,
+{
+    Ok(Arc::new(BooleanArray::from_unary(
+        from.as_primitive::<FROM>(),
+        cast_num_to_bool,
+    )))
+}
+
+/// Cast numeric types to boolean
+#[inline]
+pub fn cast_num_to_bool<I>(value: I) -> bool
+where
+    I: Default + PartialEq,
+{
+    value != I::default()
+}
+
+/// Cast Boolean types to numeric
+///
+/// `false` returns 0 while `true` returns 1
+pub(crate) fn cast_bool_to_numeric<TO>(
+    from: &dyn Array,
+    cast_options: &CastOptions,
+) -> Result<ArrayRef, ArrowError>
+where
+    TO: ArrowPrimitiveType,
+{
+    Ok(Arc::new(bool_to_numeric_cast::<TO>(
+        from.as_any().downcast_ref::<BooleanArray>().unwrap(),
+        cast_options,
+    )))
+}
+
+fn bool_to_numeric_cast<T>(from: &BooleanArray, _cast_options: &CastOptions) 
-> PrimitiveArray<T>
+where
+    T: ArrowPrimitiveType,
+{
+    let to_numeric = |bits: u64, i: usize| {
+        if bits & (1 << i) != 0 {
+            T::Native::ONE
+        } else {
+            T::Native::ZERO
+        }
+    };
+    // Unpack a 64-bit word at a time: the fixed-size inner loop helps the
+    // compiler vectorize the conversion.
+    let chunks = from.values().bit_chunks();
+    let mut values = Vec::with_capacity(from.len());
+    for bits in &chunks {
+        values.extend((0..64).map(|i| to_numeric(bits, i)));
+    }
+    let bits = chunks.remainder_bits();
+    values.extend((0..chunks.remainder_len()).map(|i| to_numeric(bits, i)));
+    PrimitiveArray::new(values.into(), from.nulls().cloned())
+}
+
+/// Cast single bool value to numeric value.
+#[inline]
+pub fn single_bool_to_numeric<O>(value: bool) -> Option<O>
+where
+    O: num_traits::NumCast + Default,
+{
+    if value {
+        // a workaround to cast a primitive to type O, infallible
+        num_traits::cast::cast(1)
+    } else {
+        Some(O::default())
+    }
+}

Reply via email to