This is an automated email from the ASF dual-hosted git repository.
scovich 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 5ba451531e Simplify downcast_...!() macro definitions (#9454)
5ba451531e is described below
commit 5ba451531efd2e98de38f6a8443aad605b6b5cc5
Author: Bruno <[email protected]>
AuthorDate: Thu Mar 5 04:44:44 2026 +0100
Simplify downcast_...!() macro definitions (#9454)
1. Reduce some quantifiers from `*` to `?` when 2+ occurrences would
generate invalid Rust code. `$(if $pred:expr)*`
2. Clean up 4-armed recursive macros:
* put the base case first
* explain the fixups
* fix all at once, going directly to the base case, instead of possibly
multiple hoops
The inital motivation was getting rust-analyzer to stop choking on such
macros usage where the left-hand side was a tuple and the
right-hand-side an expr.
---
arrow-array/src/cast.rs | 107 ++++++++++++++++++++++++++----------------------
1 file changed, 58 insertions(+), 49 deletions(-)
diff --git a/arrow-array/src/cast.rs b/arrow-array/src/cast.rs
index de590ff87c..d6cc242e02 100644
--- a/arrow-array/src/cast.rs
+++ b/arrow-array/src/cast.rs
@@ -74,7 +74,7 @@ macro_rules! repeat_pat {
/// [`DataType`]: arrow_schema::DataType
#[macro_export]
macro_rules! downcast_integer {
- ($($data_type:expr),+ => ($m:path $(, $args:tt)*), $($p:pat $(if
$pred:expr)* => $fallback:expr $(,)*)*) => {
+ ($($data_type:expr),+ => ($m:path $(, $args:tt)*), $($p:pat $(if
$pred:expr)? => $fallback:expr $(,)?)*) => {
match ($($data_type),+) {
$crate::repeat_pat!($crate::cast::__private::DataType::Int8,
$($data_type),+) => {
$m!($crate::types::Int8Type $(, $args)*)
@@ -100,7 +100,7 @@ macro_rules! downcast_integer {
$crate::repeat_pat!($crate::cast::__private::DataType::UInt64,
$($data_type),+) => {
$m!($crate::types::UInt64Type $(, $args)*)
}
- $($p $(if $pred)* => $fallback,)*
+ $($p $(if $pred)? => $fallback,)*
}
};
}
@@ -138,21 +138,24 @@ macro_rules! downcast_integer {
/// [`DataType`]: arrow_schema::DataType
#[macro_export]
macro_rules! downcast_integer_array {
- ($values:ident => $e:expr, $($p:pat $(if $pred:expr)* => $fallback:expr
$(,)*)*) => {
- $crate::downcast_integer_array!($values => {$e} $($p $(if $pred)* =>
$fallback)*)
- };
- (($($values:ident),+) => $e:expr, $($p:pat $(if $pred:expr)* =>
$fallback:expr $(,)*)*) => {
- $crate::downcast_integer_array!($($values),+ => {$e} $($p $(if $pred)*
=> $fallback)*)
- };
- ($($values:ident),+ => $e:block $($p:pat $(if $pred:expr)* =>
$fallback:expr $(,)*)*) => {
- $crate::downcast_integer_array!(($($values),+) => $e $($p $(if $pred)*
=> $fallback)*)
- };
- (($($values:ident),+) => $e:block $($p:pat $(if $pred:expr)* =>
$fallback:expr $(,)*)*) => {
+ ($($values:ident),+ => $e:block $($p:pat $(if $pred:expr)? =>
$fallback:expr $(,)?)*) => {
$crate::downcast_integer!{
$($values.data_type()),+ =>
($crate::downcast_primitive_array_helper, $($values),+, $e),
- $($p $(if $pred)* => $fallback,)*
+ $($p $(if $pred)? => $fallback,)*
}
};
+ // Turn $e into a block.
+ ($values:ident => $e:expr, $($p:pat $(if $pred:expr)? => $fallback:expr
$(,)?)*) => {
+ $crate::downcast_integer_array!($values => {$e} $($p $(if $pred)? =>
$fallback,)*)
+ };
+ // Remove $values parentheses.
+ (($($values:ident),+) => $e:block $($p:pat $(if $pred:expr)? =>
$fallback:expr $(,)?)*) => {
+ $crate::downcast_integer_array!($($values),+ => $e $($p $(if $pred)?
=> $fallback,)*)
+ };
+ // Turn $e into a block & remove $values parentheses.
+ (($($values:ident),+) => $e:expr, $($p:pat $(if $pred:expr)? =>
$fallback:expr $(,)?)*) => {
+ $crate::downcast_integer_array!($($values),+ => {$e} $($p $(if $pred)?
=> $fallback,)*)
+ };
}
/// Given one or more expressions evaluating to an integer [`DataType`]
invokes the provided macro
@@ -189,7 +192,7 @@ macro_rules! downcast_integer_array {
/// [`DataType`]: arrow_schema::DataType
#[macro_export]
macro_rules! downcast_run_end_index {
- ($($data_type:expr),+ => ($m:path $(, $args:tt)*), $($p:pat $(if
$pred:expr)* => $fallback:expr $(,)*)*) => {
+ ($($data_type:expr),+ => ($m:path $(, $args:tt)*), $($p:pat $(if
$pred:expr)? => $fallback:expr $(,)?)*) => {
match ($($data_type),+) {
$crate::repeat_pat!($crate::cast::__private::DataType::Int16,
$($data_type),+) => {
$m!($crate::types::Int16Type $(, $args)*)
@@ -200,7 +203,7 @@ macro_rules! downcast_run_end_index {
$crate::repeat_pat!($crate::cast::__private::DataType::Int64,
$($data_type),+) => {
$m!($crate::types::Int64Type $(, $args)*)
}
- $($p $(if $pred)* => $fallback,)*
+ $($p $(if $pred)? => $fallback,)*
}
};
}
@@ -234,7 +237,7 @@ macro_rules! downcast_run_end_index {
/// [`DataType`]: arrow_schema::DataType
#[macro_export]
macro_rules! downcast_temporal {
- ($($data_type:expr),+ => ($m:path $(, $args:tt)*), $($p:pat $(if
$pred:expr)* => $fallback:expr $(,)*)*) => {
+ ($($data_type:expr),+ => ($m:path $(, $args:tt)*), $($p:pat $(if
$pred:expr)? => $fallback:expr $(,)?)*) => {
match ($($data_type),+) {
$crate::repeat_pat!($crate::cast::__private::DataType::Time32($crate::cast::__private::TimeUnit::Second),
$($data_type),+) => {
$m!($crate::types::Time32SecondType $(, $args)*)
@@ -266,7 +269,7 @@ macro_rules! downcast_temporal {
$crate::repeat_pat!($crate::cast::__private::DataType::Timestamp($crate::cast::__private::TimeUnit::Nanosecond,
_), $($data_type),+) => {
$m!($crate::types::TimestampNanosecondType $(, $args)*)
}
- $($p $(if $pred)* => $fallback,)*
+ $($p $(if $pred)? => $fallback,)*
}
};
}
@@ -304,21 +307,24 @@ macro_rules! downcast_temporal {
/// [`DataType`]: arrow_schema::DataType
#[macro_export]
macro_rules! downcast_temporal_array {
- ($values:ident => $e:expr, $($p:pat $(if $pred:expr)* => $fallback:expr
$(,)*)*) => {
- $crate::downcast_temporal_array!($values => {$e} $($p $(if $pred)* =>
$fallback)*)
- };
- (($($values:ident),+) => $e:expr, $($p:pat $(if $pred:expr)* =>
$fallback:expr $(,)*)*) => {
- $crate::downcast_temporal_array!($($values),+ => {$e} $($p $(if
$pred)* => $fallback)*)
- };
- ($($values:ident),+ => $e:block $($p:pat $(if $pred:expr)* =>
$fallback:expr $(,)*)*) => {
- $crate::downcast_temporal_array!(($($values),+) => $e $($p $(if
$pred)* => $fallback)*)
- };
- (($($values:ident),+) => $e:block $($p:pat $(if $pred:expr)* =>
$fallback:expr $(,)*)*) => {
+ ($($values:ident),+ => $e:block $($p:pat $(if $pred:expr)? =>
$fallback:expr $(,)?)*) => {
$crate::downcast_temporal!{
$($values.data_type()),+ =>
($crate::downcast_primitive_array_helper, $($values),+, $e),
- $($p $(if $pred)* => $fallback,)*
+ $($p $(if $pred)? => $fallback,)*
}
};
+ // Turn $e into a block.
+ ($values:ident => $e:expr, $($p:pat $(if $pred:expr)? => $fallback:expr
$(,)?)*) => {
+ $crate::downcast_temporal_array!($values => {$e} $($p $(if $pred)? =>
$fallback,)*)
+ };
+ // Remove $values parentheses.
+ (($($values:ident),+) => $e:block $($p:pat $(if $pred:expr)? =>
$fallback:expr $(,)?)*) => {
+ $crate::downcast_temporal_array!($($values),+ => $e $($p $(if $pred)?
=> $fallback,)*)
+ };
+ // Turn $e into a block & remove $values parentheses.
+ (($($values:ident),+) => $e:expr, $($p:pat $(if $pred:expr)? =>
$fallback:expr $(,)?)*) => {
+ $crate::downcast_temporal_array!($($values),+ => {$e} $($p $(if
$pred)? => $fallback,)*)
+ };
}
/// Given one or more expressions evaluating to primitive [`DataType`] invokes
the provided macro
@@ -353,7 +359,7 @@ macro_rules! downcast_temporal_array {
/// [`DataType`]: arrow_schema::DataType
#[macro_export]
macro_rules! downcast_primitive {
- ($($data_type:expr),+ => ($m:path $(, $args:tt)*), $($p:pat $(if
$pred:expr)* => $fallback:expr $(,)*)*) => {
+ ($($data_type:expr),+ => ($m:path $(, $args:tt)*), $($p:pat $(if
$pred:expr)? => $fallback:expr $(,)?)*) => {
$crate::downcast_integer! {
$($data_type),+ => ($m $(, $args)*),
$crate::repeat_pat!($crate::cast::__private::DataType::Float16,
$($data_type),+) => {
@@ -401,7 +407,7 @@ macro_rules! downcast_primitive {
_ => {
$crate::downcast_temporal! {
$($data_type),+ => ($m $(, $args)*),
- $($p $(if $pred)* => $fallback,)*
+ $($p $(if $pred)? => $fallback,)*
}
}
}
@@ -450,21 +456,24 @@ macro_rules! downcast_primitive_array_helper {
/// [`DataType`]: arrow_schema::DataType
#[macro_export]
macro_rules! downcast_primitive_array {
- ($values:ident => $e:expr, $($p:pat $(if $pred:expr)* => $fallback:expr
$(,)*)*) => {
- $crate::downcast_primitive_array!($values => {$e} $($p $(if $pred)* =>
$fallback)*)
- };
- (($($values:ident),+) => $e:expr, $($p:pat $(if $pred:expr)* =>
$fallback:expr $(,)*)*) => {
- $crate::downcast_primitive_array!($($values),+ => {$e} $($p $(if
$pred)* => $fallback)*)
- };
- ($($values:ident),+ => $e:block $($p:pat $(if $pred:expr)* =>
$fallback:expr $(,)*)*) => {
- $crate::downcast_primitive_array!(($($values),+) => $e $($p $(if
$pred)* => $fallback)*)
- };
- (($($values:ident),+) => $e:block $($p:pat $(if $pred:expr)* =>
$fallback:expr $(,)*)*) => {
+ ($($values:ident),+ => $e:block $($p:pat $(if $pred:expr)? =>
$fallback:expr $(,)?)*) => {
$crate::downcast_primitive!{
$($values.data_type()),+ =>
($crate::downcast_primitive_array_helper, $($values),+, $e),
- $($p $(if $pred)* => $fallback,)*
+ $($p $(if $pred)? => $fallback,)*
}
};
+ // Turn $e into a block.
+ ($values:ident => $e:expr, $($p:pat $(if $pred:expr)? => $fallback:expr
$(,)?)*) => {
+ $crate::downcast_primitive_array!($values => {$e} $($p $(if $pred)? =>
$fallback,)*)
+ };
+ // Remove $values parentheses.
+ (($($values:ident),+) => $e:block $($p:pat $(if $pred:expr)? =>
$fallback:expr $(,)?)*) => {
+ $crate::downcast_primitive_array!($($values),+ => $e $($p $(if $pred)?
=> $fallback,)*)
+ };
+ // Turn $e into a block & remove $values parentheses.
+ (($($values:ident),+) => $e:expr, $($p:pat $(if $pred:expr)? =>
$fallback:expr $(,)?)*) => {
+ $crate::downcast_primitive_array!($($values),+ => {$e} $($p $(if
$pred)? => $fallback,)*)
+ };
}
/// Force downcast of an [`Array`], such as an [`ArrayRef`], to
@@ -546,11 +555,11 @@ macro_rules! downcast_dictionary_array_helper {
/// [`DataType`]: arrow_schema::DataType
#[macro_export]
macro_rules! downcast_dictionary_array {
- ($values:ident => $e:expr, $($p:pat $(if $pred:expr)* => $fallback:expr
$(,)*)*) => {
- downcast_dictionary_array!($values => {$e} $($p $(if $pred)* =>
$fallback)*)
+ ($values:ident => $e:expr, $($p:pat $(if $pred:expr)? => $fallback:expr
$(,)?)*) => {
+ downcast_dictionary_array!($values => {$e} $($p $(if $pred)? =>
$fallback,)*)
};
- ($values:ident => $e:block $($p:pat $(if $pred:expr)* => $fallback:expr
$(,)*)*) => {
+ ($values:ident => $e:block $($p:pat $(if $pred:expr)? => $fallback:expr
$(,)?)*) => {
match $values.data_type() {
$crate::cast::__private::DataType::Dictionary(k, _) => {
$crate::downcast_integer! {
@@ -558,7 +567,7 @@ macro_rules! downcast_dictionary_array {
k => unreachable!("unsupported dictionary key type: {}", k)
}
}
- $($p $(if $pred)* => $fallback,)*
+ $($p $(if $pred)? => $fallback,)*
}
}
}
@@ -654,11 +663,11 @@ macro_rules! downcast_run_array_helper {
/// [`DataType`]: arrow_schema::DataType
#[macro_export]
macro_rules! downcast_run_array {
- ($values:ident => $e:expr, $($p:pat $(if $pred:expr)* => $fallback:expr
$(,)*)*) => {
- downcast_run_array!($values => {$e} $($p $(if $pred)* => $fallback)*)
+ ($values:ident => $e:expr, $($p:pat $(if $pred:expr)? => $fallback:expr
$(,)?)*) => {
+ downcast_run_array!($values => {$e} $($p $(if $pred)? => $fallback,)*)
};
- ($values:ident => $e:block $($p:pat $(if $pred:expr)* => $fallback:expr
$(,)*)*) => {
+ ($values:ident => $e:block $($p:pat $(if $pred:expr)? => $fallback:expr
$(,)?)*) => {
match $values.data_type() {
$crate::cast::__private::DataType::RunEndEncoded(k, _) => {
$crate::downcast_run_end_index! {
@@ -666,7 +675,7 @@ macro_rules! downcast_run_array {
k => unreachable!("unsupported run end index type: {}", k)
}
}
- $($p $(if $pred)* => $fallback,)*
+ $($p $(if $pred)? => $fallback,)*
}
}
}