1use std::sync::Arc;
7
8use vortex_dtype::{DType, ExtDType, FieldName, FieldNames, PType};
9use vortex_error::{VortexExpect, VortexResult, vortex_err, vortex_panic};
10
11use crate::compute::sum;
12use crate::{Array, ArrayRef};
13
14pub trait NullArrayTrait {}
15
16pub trait BoolArrayTrait: Array {}
17
18impl dyn BoolArrayTrait + '_ {
19 pub fn true_count(&self) -> VortexResult<usize> {
20 let true_count = sum(self)?;
21 Ok(true_count
22 .as_primitive()
23 .as_::<usize>()
24 .vortex_expect("true count should never overflow usize")
25 .vortex_expect("true count should never be null"))
26 }
27}
28
29pub trait PrimitiveArrayTrait: Array {
30 fn ptype(&self) -> PType {
35 if let DType::Primitive(ptype, ..) = self.dtype() {
36 *ptype
37 } else {
38 vortex_panic!("array must have primitive data type");
39 }
40 }
41}
42
43pub trait Utf8ArrayTrait {}
44
45pub trait BinaryArrayTrait {}
46
47pub trait StructArrayTrait: Array {
48 fn names(&self) -> &FieldNames {
49 let DType::Struct(st, _) = self.dtype() else {
50 unreachable!()
51 };
52 st.names()
53 }
54
55 fn dtypes(&self) -> Vec<DType> {
56 let DType::Struct(st, _) = self.dtype() else {
57 unreachable!()
58 };
59 st.fields().collect()
60 }
61
62 fn nfields(&self) -> usize {
63 self.names().len()
64 }
65
66 fn maybe_null_field_by_idx(&self, idx: usize) -> VortexResult<ArrayRef>;
68
69 fn maybe_null_field_by_name(&self, name: &str) -> VortexResult<ArrayRef> {
71 let field_idx = self
72 .names()
73 .iter()
74 .position(|field_name| field_name.as_ref() == name)
75 .ok_or_else(|| vortex_err!("Field not found: {}", name))?;
76 self.maybe_null_field_by_idx(field_idx)
77 }
78
79 fn project(&self, projection: &[FieldName]) -> VortexResult<ArrayRef>;
80}
81
82impl dyn StructArrayTrait + '_ {
83 pub fn fields(&self) -> impl Iterator<Item = ArrayRef> + '_ {
84 (0..self.nfields()).map(|i| {
85 self.maybe_null_field_by_idx(i)
86 .vortex_expect("never out of bounds")
87 })
88 }
89}
90
91pub trait ListArrayTrait {}
92
93pub trait ExtensionArrayTrait: Array {
94 fn ext_dtype(&self) -> &Arc<ExtDType> {
96 let DType::Extension(ext_dtype) = self.dtype() else {
97 vortex_panic!("Expected ExtDType")
98 };
99 ext_dtype
100 }
101
102 fn storage_data(&self) -> ArrayRef;
104}