alamb commented on code in PR #3912:
URL: https://github.com/apache/arrow-rs/pull/3912#discussion_r1146547284
##########
arrow-ord/src/comparison.rs:
##########
@@ -893,14 +875,8 @@ pub fn lt_eq_dyn_binary_scalar(
right: &[u8],
) -> Result<BooleanArray, ArrowError> {
match left.data_type() {
- DataType::Binary => {
- let left = as_generic_binary_array::<i32>(left);
- lt_eq_binary_scalar(left, right)
- }
- DataType::LargeBinary => {
- let left = as_generic_binary_array::<i64>(left);
- lt_eq_binary_scalar(left, right)
- }
+ DataType::Binary => lt_eq_binary_scalar(left.as_binary::<i32>(),
right),
Review Comment:
it sure looks nicer
##########
arrow-array/src/cast.rs:
##########
@@ -709,6 +709,165 @@ where
T::from(array.to_data())
}
+mod private {
+ pub trait Sealed {}
+}
+
+/// An extension trait for `dyn Array` that provides ergonomic downcasting
+///
+/// ```
+/// # use std::sync::Arc;
+/// # use arrow_array::{ArrayRef, Int32Array};
+/// # use arrow_array::cast::AsArray;
+/// # use arrow_array::types::Int32Type;
+/// let col = Arc::new(Int32Array::from(vec![1, 2, 3])) as ArrayRef;
+/// assert_eq!(col.as_primitive::<Int32Type>().values(), &[1, 2, 3]);
+/// ```
+pub trait AsArray: private::Sealed {
+ /// Downcast this to a [`BooleanArray`] returning `None` if not possible
+ fn as_boolean_opt(&self) -> Option<&BooleanArray>;
+
+ /// Downcast this to a [`BooleanArray`] panicking if not possible
+ fn as_boolean(&self) -> &BooleanArray {
+ self.as_boolean_opt().expect("boolean array")
+ }
+
+ /// Downcast this to a [`PrimitiveArray`] returning `None` if not possible
+ fn as_primitive_opt<T: ArrowPrimitiveType>(&self) ->
Option<&PrimitiveArray<T>>;
+
+ /// Downcast this to a [`PrimitiveArray`] panicking if not possible
+ fn as_primitive<T: ArrowPrimitiveType>(&self) -> &PrimitiveArray<T> {
+ self.as_primitive_opt().expect("primitive array")
+ }
+
+ /// Downcast this to a [`GenericByteArray`] returning `None` if not
possible
+ fn as_bytes_opt<T: ByteArrayType>(&self) -> Option<&GenericByteArray<T>>;
+
+ /// Downcast this to a [`GenericByteArray`] panicking if not possible
+ fn as_bytes<T: ByteArrayType>(&self) -> &GenericByteArray<T> {
+ self.as_bytes_opt().expect("byte array")
+ }
+
+ /// Downcast this to a [`GenericStringArray`] returning `None` if not
possible
+ fn as_string_opt<O: OffsetSizeTrait>(&self) ->
Option<&GenericStringArray<O>> {
+ self.as_bytes_opt()
+ }
+
+ /// Downcast this to a [`GenericStringArray`] panicking if not possible
+ fn as_string<O: OffsetSizeTrait>(&self) -> &GenericStringArray<O> {
+ self.as_bytes_opt().expect("string array")
+ }
+
+ /// Downcast this to a [`GenericBinaryArray`] returning `None` if not
possible
+ fn as_binary_opt<O: OffsetSizeTrait>(&self) ->
Option<&GenericBinaryArray<O>> {
+ self.as_bytes_opt()
+ }
+
+ /// Downcast this to a [`GenericBinaryArray`] panicking if not possible
+ fn as_binary<O: OffsetSizeTrait>(&self) -> &GenericBinaryArray<O> {
+ self.as_bytes_opt().expect("binary array")
+ }
+
+ /// Downcast this to a [`StructArray`] returning `None` if not possible
+ fn as_struct_opt(&self) -> Option<&StructArray>;
+
+ /// Downcast this to a [`StructArray`] panicking if not possible
+ fn as_struct(&self) -> &StructArray {
+ self.as_struct_opt().expect("struct array")
+ }
+
+ /// Downcast this to a [`GenericListArray`] returning `None` if not
possible
+ fn as_list_opt<O: OffsetSizeTrait>(&self) -> Option<&GenericListArray<O>>;
+
+ /// Downcast this to a [`GenericListArray`] panicking if not possible
+ fn as_list<O: OffsetSizeTrait>(&self) -> &GenericListArray<O> {
+ self.as_list_opt().expect("list array")
+ }
+
+ /// Downcast this to a [`MapArray`] returning `None` if not possible
+ fn as_map_opt(&self) -> Option<&MapArray>;
+
+ /// Downcast this to a [`MapArray`] panicking if not possible
+ fn as_map(&self) -> &MapArray {
+ self.as_map_opt().expect("map array")
+ }
+
+ /// Downcast this to a [`DictionaryArray`] returning `None` if not possible
+ fn as_dictionary_opt<K: ArrowDictionaryKeyType>(&self)
+ -> Option<&DictionaryArray<K>>;
+
+ /// Downcast this to a [`DictionaryArray`] panicking if not possible
+ fn as_dictionary<K: ArrowDictionaryKeyType>(&self) -> &DictionaryArray<K> {
+ self.as_dictionary_opt().expect("dictionary array")
+ }
+}
+
+impl private::Sealed for dyn Array + '_ {}
+impl AsArray for dyn Array + '_ {
+ fn as_boolean_opt(&self) -> Option<&BooleanArray> {
+ self.as_any().downcast_ref()
Review Comment:
this is very clever 👍
##########
arrow-array/src/builder/generic_byte_run_builder.rs:
##########
@@ -368,7 +368,7 @@ pub type LargeStringRunBuilder<K> =
GenericByteRunBuilder<K, LargeUtf8Type>;
///
/// // Values are polymorphic and so require a downcast.
/// let av = array.values();
-/// let ava: &BinaryArray = as_generic_binary_array::<i32>(av.as_ref());
+/// let ava: &BinaryArray = av.as_binary();
Review Comment:
this is much nicer -- I hit this with @appletreeisyellow when trying to
downcast to a `BinaryArray` (having to know to put i32 was non obvious)
##########
arrow-array/src/cast.rs:
##########
@@ -709,6 +709,165 @@ where
T::from(array.to_data())
}
+mod private {
+ pub trait Sealed {}
+}
+
+/// An extension trait for `dyn Array` that provides ergonomic downcasting
+///
+/// ```
+/// # use std::sync::Arc;
+/// # use arrow_array::{ArrayRef, Int32Array};
+/// # use arrow_array::cast::AsArray;
+/// # use arrow_array::types::Int32Type;
+/// let col = Arc::new(Int32Array::from(vec![1, 2, 3])) as ArrayRef;
+/// assert_eq!(col.as_primitive::<Int32Type>().values(), &[1, 2, 3]);
+/// ```
+pub trait AsArray: private::Sealed {
+ /// Downcast this to a [`BooleanArray`] returning `None` if not possible
+ fn as_boolean_opt(&self) -> Option<&BooleanArray>;
Review Comment:
I like how you have provided both `_opt` and non `_opt` variants so users
can choose
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]