1use crate::array::*;
21use crate::types::*;
22use arrow_data::ArrayData;
23
24#[doc(hidden)]
28pub mod __private {
29    pub use arrow_schema::{DataType, IntervalUnit, TimeUnit};
30}
31
32#[doc(hidden)]
34#[macro_export]
35macro_rules! repeat_pat {
36    ($e:pat, $v_:expr) => {
37        $e
38    };
39    ($e:pat, $v_:expr $(, $tail:expr)+) => {
40        ($e, $crate::repeat_pat!($e $(, $tail)+))
41    }
42}
43
44#[macro_export]
76macro_rules! downcast_integer {
77    ($($data_type:expr),+ => ($m:path $(, $args:tt)*), $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
78        match ($($data_type),+) {
79            $crate::repeat_pat!($crate::cast::__private::DataType::Int8, $($data_type),+) => {
80                $m!($crate::types::Int8Type $(, $args)*)
81            }
82            $crate::repeat_pat!($crate::cast::__private::DataType::Int16, $($data_type),+) => {
83                $m!($crate::types::Int16Type $(, $args)*)
84            }
85            $crate::repeat_pat!($crate::cast::__private::DataType::Int32, $($data_type),+) => {
86                $m!($crate::types::Int32Type $(, $args)*)
87            }
88            $crate::repeat_pat!($crate::cast::__private::DataType::Int64, $($data_type),+) => {
89                $m!($crate::types::Int64Type $(, $args)*)
90            }
91            $crate::repeat_pat!($crate::cast::__private::DataType::UInt8, $($data_type),+) => {
92                $m!($crate::types::UInt8Type $(, $args)*)
93            }
94            $crate::repeat_pat!($crate::cast::__private::DataType::UInt16, $($data_type),+) => {
95                $m!($crate::types::UInt16Type $(, $args)*)
96            }
97            $crate::repeat_pat!($crate::cast::__private::DataType::UInt32, $($data_type),+) => {
98                $m!($crate::types::UInt32Type $(, $args)*)
99            }
100            $crate::repeat_pat!($crate::cast::__private::DataType::UInt64, $($data_type),+) => {
101                $m!($crate::types::UInt64Type $(, $args)*)
102            }
103            $($p $(if $pred)* => $fallback,)*
104        }
105    };
106}
107
108#[macro_export]
140macro_rules! downcast_integer_array {
141    ($values:ident => $e:expr, $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
142        $crate::downcast_integer_array!($values => {$e} $($p $(if $pred)* => $fallback)*)
143    };
144    (($($values:ident),+) => $e:expr, $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
145        $crate::downcast_integer_array!($($values),+ => {$e} $($p $(if $pred)* => $fallback)*)
146    };
147    ($($values:ident),+ => $e:block $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
148        $crate::downcast_integer_array!(($($values),+) => $e $($p $(if $pred)* => $fallback)*)
149    };
150    (($($values:ident),+) => $e:block $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
151        $crate::downcast_integer!{
152            $($values.data_type()),+ => ($crate::downcast_primitive_array_helper, $($values),+, $e),
153            $($p $(if $pred)* => $fallback,)*
154        }
155    };
156}
157
158#[macro_export]
191macro_rules! downcast_run_end_index {
192    ($($data_type:expr),+ => ($m:path $(, $args:tt)*), $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
193        match ($($data_type),+) {
194            $crate::repeat_pat!($crate::cast::__private::DataType::Int16, $($data_type),+) => {
195                $m!($crate::types::Int16Type $(, $args)*)
196            }
197            $crate::repeat_pat!($crate::cast::__private::DataType::Int32, $($data_type),+) => {
198                $m!($crate::types::Int32Type $(, $args)*)
199            }
200            $crate::repeat_pat!($crate::cast::__private::DataType::Int64, $($data_type),+) => {
201                $m!($crate::types::Int64Type $(, $args)*)
202            }
203            $($p $(if $pred)* => $fallback,)*
204        }
205    };
206}
207
208#[macro_export]
236macro_rules! downcast_temporal {
237    ($($data_type:expr),+ => ($m:path $(, $args:tt)*), $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
238        match ($($data_type),+) {
239            $crate::repeat_pat!($crate::cast::__private::DataType::Time32($crate::cast::__private::TimeUnit::Second), $($data_type),+) => {
240                $m!($crate::types::Time32SecondType $(, $args)*)
241            }
242            $crate::repeat_pat!($crate::cast::__private::DataType::Time32($crate::cast::__private::TimeUnit::Millisecond), $($data_type),+) => {
243                $m!($crate::types::Time32MillisecondType $(, $args)*)
244            }
245            $crate::repeat_pat!($crate::cast::__private::DataType::Time64($crate::cast::__private::TimeUnit::Microsecond), $($data_type),+) => {
246                $m!($crate::types::Time64MicrosecondType $(, $args)*)
247            }
248            $crate::repeat_pat!($crate::cast::__private::DataType::Time64($crate::cast::__private::TimeUnit::Nanosecond), $($data_type),+) => {
249                $m!($crate::types::Time64NanosecondType $(, $args)*)
250            }
251            $crate::repeat_pat!($crate::cast::__private::DataType::Date32, $($data_type),+) => {
252                $m!($crate::types::Date32Type $(, $args)*)
253            }
254            $crate::repeat_pat!($crate::cast::__private::DataType::Date64, $($data_type),+) => {
255                $m!($crate::types::Date64Type $(, $args)*)
256            }
257            $crate::repeat_pat!($crate::cast::__private::DataType::Timestamp($crate::cast::__private::TimeUnit::Second, _), $($data_type),+) => {
258                $m!($crate::types::TimestampSecondType $(, $args)*)
259            }
260            $crate::repeat_pat!($crate::cast::__private::DataType::Timestamp($crate::cast::__private::TimeUnit::Millisecond, _), $($data_type),+) => {
261                $m!($crate::types::TimestampMillisecondType $(, $args)*)
262            }
263            $crate::repeat_pat!($crate::cast::__private::DataType::Timestamp($crate::cast::__private::TimeUnit::Microsecond, _), $($data_type),+) => {
264                $m!($crate::types::TimestampMicrosecondType $(, $args)*)
265            }
266            $crate::repeat_pat!($crate::cast::__private::DataType::Timestamp($crate::cast::__private::TimeUnit::Nanosecond, _), $($data_type),+) => {
267                $m!($crate::types::TimestampNanosecondType $(, $args)*)
268            }
269            $($p $(if $pred)* => $fallback,)*
270        }
271    };
272}
273
274#[macro_export]
306macro_rules! downcast_temporal_array {
307    ($values:ident => $e:expr, $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
308        $crate::downcast_temporal_array!($values => {$e} $($p $(if $pred)* => $fallback)*)
309    };
310    (($($values:ident),+) => $e:expr, $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
311        $crate::downcast_temporal_array!($($values),+ => {$e} $($p $(if $pred)* => $fallback)*)
312    };
313    ($($values:ident),+ => $e:block $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
314        $crate::downcast_temporal_array!(($($values),+) => $e $($p $(if $pred)* => $fallback)*)
315    };
316    (($($values:ident),+) => $e:block $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
317        $crate::downcast_temporal!{
318            $($values.data_type()),+ => ($crate::downcast_primitive_array_helper, $($values),+, $e),
319            $($p $(if $pred)* => $fallback,)*
320        }
321    };
322}
323
324#[macro_export]
355macro_rules! downcast_primitive {
356    ($($data_type:expr),+ => ($m:path $(, $args:tt)*), $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
357        $crate::downcast_integer! {
358            $($data_type),+ => ($m $(, $args)*),
359            $crate::repeat_pat!($crate::cast::__private::DataType::Float16, $($data_type),+) => {
360                $m!($crate::types::Float16Type $(, $args)*)
361            }
362            $crate::repeat_pat!($crate::cast::__private::DataType::Float32, $($data_type),+) => {
363                $m!($crate::types::Float32Type $(, $args)*)
364            }
365            $crate::repeat_pat!($crate::cast::__private::DataType::Float64, $($data_type),+) => {
366                $m!($crate::types::Float64Type $(, $args)*)
367            }
368            $crate::repeat_pat!($crate::cast::__private::DataType::Decimal128(_, _), $($data_type),+) => {
369                $m!($crate::types::Decimal128Type $(, $args)*)
370            }
371            $crate::repeat_pat!($crate::cast::__private::DataType::Decimal256(_, _), $($data_type),+) => {
372                $m!($crate::types::Decimal256Type $(, $args)*)
373            }
374            $crate::repeat_pat!($crate::cast::__private::DataType::Interval($crate::cast::__private::IntervalUnit::YearMonth), $($data_type),+) => {
375                $m!($crate::types::IntervalYearMonthType $(, $args)*)
376            }
377            $crate::repeat_pat!($crate::cast::__private::DataType::Interval($crate::cast::__private::IntervalUnit::DayTime), $($data_type),+) => {
378                $m!($crate::types::IntervalDayTimeType $(, $args)*)
379            }
380            $crate::repeat_pat!($crate::cast::__private::DataType::Interval($crate::cast::__private::IntervalUnit::MonthDayNano), $($data_type),+) => {
381                $m!($crate::types::IntervalMonthDayNanoType $(, $args)*)
382            }
383            $crate::repeat_pat!($crate::cast::__private::DataType::Duration($crate::cast::__private::TimeUnit::Second), $($data_type),+) => {
384                $m!($crate::types::DurationSecondType $(, $args)*)
385            }
386            $crate::repeat_pat!($crate::cast::__private::DataType::Duration($crate::cast::__private::TimeUnit::Millisecond), $($data_type),+) => {
387                $m!($crate::types::DurationMillisecondType $(, $args)*)
388            }
389            $crate::repeat_pat!($crate::cast::__private::DataType::Duration($crate::cast::__private::TimeUnit::Microsecond), $($data_type),+) => {
390                $m!($crate::types::DurationMicrosecondType $(, $args)*)
391            }
392            $crate::repeat_pat!($crate::cast::__private::DataType::Duration($crate::cast::__private::TimeUnit::Nanosecond), $($data_type),+) => {
393                $m!($crate::types::DurationNanosecondType $(, $args)*)
394            }
395            _ => {
396                $crate::downcast_temporal! {
397                    $($data_type),+ => ($m $(, $args)*),
398                    $($p $(if $pred)* => $fallback,)*
399                }
400            }
401        }
402    };
403}
404
405#[macro_export]
406#[doc(hidden)]
407macro_rules! downcast_primitive_array_helper {
408    ($t:ty, $($values:ident),+, $e:block) => {{
409        $(let $values = $crate::cast::as_primitive_array::<$t>($values);)+
410        $e
411    }};
412}
413
414#[macro_export]
446macro_rules! downcast_primitive_array {
447    ($values:ident => $e:expr, $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
448        $crate::downcast_primitive_array!($values => {$e} $($p $(if $pred)* => $fallback)*)
449    };
450    (($($values:ident),+) => $e:expr, $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
451        $crate::downcast_primitive_array!($($values),+ => {$e} $($p $(if $pred)* => $fallback)*)
452    };
453    ($($values:ident),+ => $e:block $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
454        $crate::downcast_primitive_array!(($($values),+) => $e $($p $(if $pred)* => $fallback)*)
455    };
456    (($($values:ident),+) => $e:block $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
457        $crate::downcast_primitive!{
458            $($values.data_type()),+ => ($crate::downcast_primitive_array_helper, $($values),+, $e),
459            $($p $(if $pred)* => $fallback,)*
460        }
461    };
462}
463
464pub fn as_primitive_array<T>(arr: &dyn Array) -> &PrimitiveArray<T>
490where
491    T: ArrowPrimitiveType,
492{
493    arr.as_any()
494        .downcast_ref::<PrimitiveArray<T>>()
495        .expect("Unable to downcast to primitive array")
496}
497
498#[macro_export]
499#[doc(hidden)]
500macro_rules! downcast_dictionary_array_helper {
501    ($t:ty, $($values:ident),+, $e:block) => {{
502        $(let $values = $crate::cast::as_dictionary_array::<$t>($values);)+
503        $e
504    }};
505}
506
507#[macro_export]
542macro_rules! downcast_dictionary_array {
543    ($values:ident => $e:expr, $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
544        downcast_dictionary_array!($values => {$e} $($p $(if $pred)* => $fallback)*)
545    };
546
547    ($values:ident => $e:block $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
548        match $values.data_type() {
549            $crate::cast::__private::DataType::Dictionary(k, _) => {
550                $crate::downcast_integer! {
551                    k.as_ref() => ($crate::downcast_dictionary_array_helper, $values, $e),
552                    k => unreachable!("unsupported dictionary key type: {}", k)
553                }
554            }
555            $($p $(if $pred)* => $fallback,)*
556        }
557    }
558}
559
560pub fn as_dictionary_array<T>(arr: &dyn Array) -> &DictionaryArray<T>
575where
576    T: ArrowDictionaryKeyType,
577{
578    arr.as_any()
579        .downcast_ref::<DictionaryArray<T>>()
580        .expect("Unable to downcast to dictionary array")
581}
582
583pub fn as_run_array<T>(arr: &dyn Array) -> &RunArray<T>
598where
599    T: RunEndIndexType,
600{
601    arr.as_any()
602        .downcast_ref::<RunArray<T>>()
603        .expect("Unable to downcast to run array")
604}
605
606#[macro_export]
607#[doc(hidden)]
608macro_rules! downcast_run_array_helper {
609    ($t:ty, $($values:ident),+, $e:block) => {{
610        $(let $values = $crate::cast::as_run_array::<$t>($values);)+
611        $e
612    }};
613}
614
615#[macro_export]
650macro_rules! downcast_run_array {
651    ($values:ident => $e:expr, $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
652        downcast_run_array!($values => {$e} $($p $(if $pred)* => $fallback)*)
653    };
654
655    ($values:ident => $e:block $($p:pat $(if $pred:expr)* => $fallback:expr $(,)*)*) => {
656        match $values.data_type() {
657            $crate::cast::__private::DataType::RunEndEncoded(k, _) => {
658                $crate::downcast_run_end_index! {
659                    k.data_type() => ($crate::downcast_run_array_helper, $values, $e),
660                    k => unreachable!("unsupported run end index type: {}", k)
661                }
662            }
663            $($p $(if $pred)* => $fallback,)*
664        }
665    }
666}
667
668pub fn as_generic_list_array<S: OffsetSizeTrait>(arr: &dyn Array) -> &GenericListArray<S> {
671    arr.as_any()
672        .downcast_ref::<GenericListArray<S>>()
673        .expect("Unable to downcast to list array")
674}
675
676#[inline]
679pub fn as_list_array(arr: &dyn Array) -> &ListArray {
680    as_generic_list_array::<i32>(arr)
681}
682
683#[inline]
686pub fn as_fixed_size_list_array(arr: &dyn Array) -> &FixedSizeListArray {
687    arr.as_any()
688        .downcast_ref::<FixedSizeListArray>()
689        .expect("Unable to downcast to fixed size list array")
690}
691
692#[inline]
695pub fn as_large_list_array(arr: &dyn Array) -> &LargeListArray {
696    as_generic_list_array::<i64>(arr)
697}
698
699#[inline]
702pub fn as_generic_binary_array<S: OffsetSizeTrait>(arr: &dyn Array) -> &GenericBinaryArray<S> {
703    arr.as_any()
704        .downcast_ref::<GenericBinaryArray<S>>()
705        .expect("Unable to downcast to binary array")
706}
707
708pub fn as_string_array(arr: &dyn Array) -> &StringArray {
722    arr.as_any()
723        .downcast_ref::<StringArray>()
724        .expect("Unable to downcast to StringArray")
725}
726
727pub fn as_boolean_array(arr: &dyn Array) -> &BooleanArray {
741    arr.as_any()
742        .downcast_ref::<BooleanArray>()
743        .expect("Unable to downcast to BooleanArray")
744}
745
746macro_rules! array_downcast_fn {
747    ($name: ident, $arrty: ty, $arrty_str:expr) => {
748        #[doc = "Force downcast of an [`Array`], such as an [`ArrayRef`] to "]
749        #[doc = $arrty_str]
750        pub fn $name(arr: &dyn Array) -> &$arrty {
751            arr.as_any().downcast_ref::<$arrty>().expect(concat!(
752                "Unable to downcast to typed array through ",
753                stringify!($name)
754            ))
755        }
756    };
757
758    ($name: ident, $arrty: ty) => {
760        array_downcast_fn!(
761            $name,
762            $arrty,
763            concat!("[`", stringify!($arrty), "`], panicking on failure.")
764        );
765    };
766}
767
768array_downcast_fn!(as_largestring_array, LargeStringArray);
769array_downcast_fn!(as_null_array, NullArray);
770array_downcast_fn!(as_struct_array, StructArray);
771array_downcast_fn!(as_union_array, UnionArray);
772array_downcast_fn!(as_map_array, MapArray);
773
774pub fn downcast_array<T>(array: &dyn Array) -> T
800where
801    T: From<ArrayData>,
802{
803    T::from(array.to_data())
804}
805
806mod private {
807    pub trait Sealed {}
808}
809
810pub trait AsArray: private::Sealed {
821    fn as_boolean_opt(&self) -> Option<&BooleanArray>;
823
824    fn as_boolean(&self) -> &BooleanArray {
826        self.as_boolean_opt().expect("boolean array")
827    }
828
829    fn as_primitive_opt<T: ArrowPrimitiveType>(&self) -> Option<&PrimitiveArray<T>>;
831
832    fn as_primitive<T: ArrowPrimitiveType>(&self) -> &PrimitiveArray<T> {
834        self.as_primitive_opt().expect("primitive array")
835    }
836
837    fn as_bytes_opt<T: ByteArrayType>(&self) -> Option<&GenericByteArray<T>>;
839
840    fn as_bytes<T: ByteArrayType>(&self) -> &GenericByteArray<T> {
842        self.as_bytes_opt().expect("byte array")
843    }
844
845    fn as_string_opt<O: OffsetSizeTrait>(&self) -> Option<&GenericStringArray<O>> {
847        self.as_bytes_opt()
848    }
849
850    fn as_string<O: OffsetSizeTrait>(&self) -> &GenericStringArray<O> {
852        self.as_bytes_opt().expect("string array")
853    }
854
855    fn as_binary_opt<O: OffsetSizeTrait>(&self) -> Option<&GenericBinaryArray<O>> {
857        self.as_bytes_opt()
858    }
859
860    fn as_binary<O: OffsetSizeTrait>(&self) -> &GenericBinaryArray<O> {
862        self.as_bytes_opt().expect("binary array")
863    }
864
865    fn as_string_view_opt(&self) -> Option<&StringViewArray> {
867        self.as_byte_view_opt()
868    }
869
870    fn as_string_view(&self) -> &StringViewArray {
872        self.as_byte_view_opt().expect("string view array")
873    }
874
875    fn as_binary_view_opt(&self) -> Option<&BinaryViewArray> {
877        self.as_byte_view_opt()
878    }
879
880    fn as_binary_view(&self) -> &BinaryViewArray {
882        self.as_byte_view_opt().expect("binary view array")
883    }
884
885    fn as_byte_view_opt<T: ByteViewType>(&self) -> Option<&GenericByteViewArray<T>>;
887
888    fn as_byte_view<T: ByteViewType>(&self) -> &GenericByteViewArray<T> {
890        self.as_byte_view_opt().expect("byte view array")
891    }
892
893    fn as_struct_opt(&self) -> Option<&StructArray>;
895
896    fn as_struct(&self) -> &StructArray {
898        self.as_struct_opt().expect("struct array")
899    }
900
901    fn as_union_opt(&self) -> Option<&UnionArray>;
903
904    fn as_union(&self) -> &UnionArray {
906        self.as_union_opt().expect("union array")
907    }
908
909    fn as_list_opt<O: OffsetSizeTrait>(&self) -> Option<&GenericListArray<O>>;
911
912    fn as_list<O: OffsetSizeTrait>(&self) -> &GenericListArray<O> {
914        self.as_list_opt().expect("list array")
915    }
916
917    fn as_list_view_opt<O: OffsetSizeTrait>(&self) -> Option<&GenericListViewArray<O>>;
919
920    fn as_list_view<O: OffsetSizeTrait>(&self) -> &GenericListViewArray<O> {
922        self.as_list_view_opt().expect("list view array")
923    }
924
925    fn as_fixed_size_binary_opt(&self) -> Option<&FixedSizeBinaryArray>;
927
928    fn as_fixed_size_binary(&self) -> &FixedSizeBinaryArray {
930        self.as_fixed_size_binary_opt()
931            .expect("fixed size binary array")
932    }
933
934    fn as_fixed_size_list_opt(&self) -> Option<&FixedSizeListArray>;
936
937    fn as_fixed_size_list(&self) -> &FixedSizeListArray {
939        self.as_fixed_size_list_opt()
940            .expect("fixed size list array")
941    }
942
943    fn as_map_opt(&self) -> Option<&MapArray>;
945
946    fn as_map(&self) -> &MapArray {
948        self.as_map_opt().expect("map array")
949    }
950
951    fn as_dictionary_opt<K: ArrowDictionaryKeyType>(&self) -> Option<&DictionaryArray<K>>;
953
954    fn as_dictionary<K: ArrowDictionaryKeyType>(&self) -> &DictionaryArray<K> {
956        self.as_dictionary_opt().expect("dictionary array")
957    }
958
959    fn as_any_dictionary_opt(&self) -> Option<&dyn AnyDictionaryArray>;
961
962    fn as_any_dictionary(&self) -> &dyn AnyDictionaryArray {
964        self.as_any_dictionary_opt().expect("any dictionary array")
965    }
966}
967
968impl private::Sealed for dyn Array + '_ {}
969impl AsArray for dyn Array + '_ {
970    fn as_boolean_opt(&self) -> Option<&BooleanArray> {
971        self.as_any().downcast_ref()
972    }
973
974    fn as_primitive_opt<T: ArrowPrimitiveType>(&self) -> Option<&PrimitiveArray<T>> {
975        self.as_any().downcast_ref()
976    }
977
978    fn as_bytes_opt<T: ByteArrayType>(&self) -> Option<&GenericByteArray<T>> {
979        self.as_any().downcast_ref()
980    }
981
982    fn as_byte_view_opt<T: ByteViewType>(&self) -> Option<&GenericByteViewArray<T>> {
983        self.as_any().downcast_ref()
984    }
985
986    fn as_struct_opt(&self) -> Option<&StructArray> {
987        self.as_any().downcast_ref()
988    }
989
990    fn as_union_opt(&self) -> Option<&UnionArray> {
991        self.as_any().downcast_ref()
992    }
993
994    fn as_list_opt<O: OffsetSizeTrait>(&self) -> Option<&GenericListArray<O>> {
995        self.as_any().downcast_ref()
996    }
997
998    fn as_list_view_opt<O: OffsetSizeTrait>(&self) -> Option<&GenericListViewArray<O>> {
999        self.as_any().downcast_ref()
1000    }
1001
1002    fn as_fixed_size_binary_opt(&self) -> Option<&FixedSizeBinaryArray> {
1003        self.as_any().downcast_ref()
1004    }
1005
1006    fn as_fixed_size_list_opt(&self) -> Option<&FixedSizeListArray> {
1007        self.as_any().downcast_ref()
1008    }
1009
1010    fn as_map_opt(&self) -> Option<&MapArray> {
1011        self.as_any().downcast_ref()
1012    }
1013
1014    fn as_dictionary_opt<K: ArrowDictionaryKeyType>(&self) -> Option<&DictionaryArray<K>> {
1015        self.as_any().downcast_ref()
1016    }
1017
1018    fn as_any_dictionary_opt(&self) -> Option<&dyn AnyDictionaryArray> {
1019        let array = self;
1020        downcast_dictionary_array! {
1021            array => Some(array),
1022            _ => None
1023        }
1024    }
1025}
1026
1027impl private::Sealed for ArrayRef {}
1028impl AsArray for ArrayRef {
1029    fn as_boolean_opt(&self) -> Option<&BooleanArray> {
1030        self.as_ref().as_boolean_opt()
1031    }
1032
1033    fn as_primitive_opt<T: ArrowPrimitiveType>(&self) -> Option<&PrimitiveArray<T>> {
1034        self.as_ref().as_primitive_opt()
1035    }
1036
1037    fn as_bytes_opt<T: ByteArrayType>(&self) -> Option<&GenericByteArray<T>> {
1038        self.as_ref().as_bytes_opt()
1039    }
1040
1041    fn as_byte_view_opt<T: ByteViewType>(&self) -> Option<&GenericByteViewArray<T>> {
1042        self.as_ref().as_byte_view_opt()
1043    }
1044
1045    fn as_struct_opt(&self) -> Option<&StructArray> {
1046        self.as_ref().as_struct_opt()
1047    }
1048
1049    fn as_union_opt(&self) -> Option<&UnionArray> {
1050        self.as_any().downcast_ref()
1051    }
1052
1053    fn as_list_opt<O: OffsetSizeTrait>(&self) -> Option<&GenericListArray<O>> {
1054        self.as_ref().as_list_opt()
1055    }
1056
1057    fn as_list_view_opt<O: OffsetSizeTrait>(&self) -> Option<&GenericListViewArray<O>> {
1058        self.as_ref().as_list_view_opt()
1059    }
1060
1061    fn as_fixed_size_binary_opt(&self) -> Option<&FixedSizeBinaryArray> {
1062        self.as_ref().as_fixed_size_binary_opt()
1063    }
1064
1065    fn as_fixed_size_list_opt(&self) -> Option<&FixedSizeListArray> {
1066        self.as_ref().as_fixed_size_list_opt()
1067    }
1068
1069    fn as_map_opt(&self) -> Option<&MapArray> {
1070        self.as_any().downcast_ref()
1071    }
1072
1073    fn as_dictionary_opt<K: ArrowDictionaryKeyType>(&self) -> Option<&DictionaryArray<K>> {
1074        self.as_ref().as_dictionary_opt()
1075    }
1076
1077    fn as_any_dictionary_opt(&self) -> Option<&dyn AnyDictionaryArray> {
1078        self.as_ref().as_any_dictionary_opt()
1079    }
1080}
1081
1082#[cfg(test)]
1083mod tests {
1084    use super::*;
1085    use arrow_buffer::i256;
1086    use arrow_schema::DataType;
1087    use std::sync::Arc;
1088
1089    #[test]
1090    fn test_as_primitive_array_ref() {
1091        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
1092        assert!(!as_primitive_array::<Int32Type>(&array).is_empty());
1093
1094        let array: ArrayRef = Arc::new(array);
1096        assert!(!as_primitive_array::<Int32Type>(&array).is_empty());
1097    }
1098
1099    #[test]
1100    fn test_as_string_array_ref() {
1101        let array: StringArray = vec!["foo", "bar"].into_iter().map(Some).collect();
1102        assert!(!as_string_array(&array).is_empty());
1103
1104        let array: ArrayRef = Arc::new(array);
1106        assert!(!as_string_array(&array).is_empty())
1107    }
1108
1109    #[test]
1110    fn test_decimal128array() {
1111        let a = Decimal128Array::from_iter_values([1, 2, 4, 5]);
1112        assert!(!as_primitive_array::<Decimal128Type>(&a).is_empty());
1113    }
1114
1115    #[test]
1116    fn test_decimal256array() {
1117        let a = Decimal256Array::from_iter_values([1, 2, 4, 5].into_iter().map(i256::from_i128));
1118        assert!(!as_primitive_array::<Decimal256Type>(&a).is_empty());
1119    }
1120
1121    #[test]
1122    fn downcast_integer_array_should_match_only_integers() {
1123        let i32_array: ArrayRef = Arc::new(Int32Array::new_null(1));
1124        let i32_array_ref = &i32_array;
1125        downcast_integer_array!(
1126            i32_array_ref => {
1127                assert_eq!(i32_array_ref.null_count(), 1);
1128            },
1129            _ => panic!("unexpected data type")
1130        );
1131    }
1132
1133    #[test]
1134    fn downcast_integer_array_should_not_match_primitive_that_are_not_integers() {
1135        let array: ArrayRef = Arc::new(Float32Array::new_null(1));
1136        let array_ref = &array;
1137        downcast_integer_array!(
1138            array_ref => {
1139                panic!("unexpected data type {}", array_ref.data_type())
1140            },
1141            DataType::Float32 => {
1142                assert_eq!(array_ref.null_count(), 1);
1143            },
1144            _ => panic!("unexpected data type")
1145        );
1146    }
1147
1148    #[test]
1149    fn downcast_integer_array_should_not_match_non_primitive() {
1150        let array: ArrayRef = Arc::new(StringArray::new_null(1));
1151        let array_ref = &array;
1152        downcast_integer_array!(
1153            array_ref => {
1154                panic!("unexpected data type {}", array_ref.data_type())
1155            },
1156            DataType::Utf8 => {
1157                assert_eq!(array_ref.null_count(), 1);
1158            },
1159            _ => panic!("unexpected data type")
1160        );
1161    }
1162}