use std::ops::Deref;
use std::sync::Arc;
use vortex_dtype::{DType, ExtDType, Field, FieldInfo, FieldName, FieldNames, PType};
use vortex_error::{vortex_panic, VortexResult};
use crate::Array;
impl Array {
pub fn as_null_array(&self) -> Option<&dyn NullArrayTrait> {
matches!(self.dtype(), DType::Null)
.then(|| self.vtable().as_null_array(self))
.flatten()
}
pub fn as_bool_array(&self) -> Option<&dyn BoolArrayTrait> {
matches!(self.dtype(), DType::Bool(..))
.then(|| self.vtable().as_bool_array(self))
.flatten()
}
pub fn as_primitive_array(&self) -> Option<&dyn PrimitiveArrayTrait> {
matches!(self.dtype(), DType::Primitive(..))
.then(|| self.vtable().as_primitive_array(self))
.flatten()
}
pub fn as_utf8_array(&self) -> Option<&dyn Utf8ArrayTrait> {
matches!(self.dtype(), DType::Utf8(..))
.then(|| self.vtable().as_utf8_array(self))
.flatten()
}
pub fn as_binary_array(&self) -> Option<&dyn BinaryArrayTrait> {
matches!(self.dtype(), DType::Binary(..))
.then(|| self.vtable().as_binary_array(self))
.flatten()
}
pub fn as_struct_array(&self) -> Option<&dyn StructArrayTrait> {
matches!(self.dtype(), DType::Struct(..))
.then(|| self.vtable().as_struct_array(self))
.flatten()
}
pub fn as_list_array(&self) -> Option<&dyn ListArrayTrait> {
matches!(self.dtype(), DType::List(..))
.then(|| self.vtable().as_list_array(self))
.flatten()
}
pub fn as_extension_array(&self) -> Option<&dyn ExtensionArrayTrait> {
matches!(self.dtype(), DType::Extension(..))
.then(|| self.vtable().as_extension_array(self))
.flatten()
}
}
pub trait NullArrayTrait {}
pub trait BoolArrayTrait {}
pub trait PrimitiveArrayTrait: Deref<Target = Array> {
fn ptype(&self) -> PType {
if let DType::Primitive(ptype, ..) = self.dtype() {
*ptype
} else {
vortex_panic!("array must have primitive data type");
}
}
}
pub trait Utf8ArrayTrait {}
pub trait BinaryArrayTrait {}
pub trait StructArrayTrait: Deref<Target = Array> {
fn names(&self) -> &FieldNames {
let DType::Struct(st, _) = self.dtype() else {
unreachable!()
};
st.names()
}
fn field_info(&self, field: &Field) -> VortexResult<FieldInfo> {
let DType::Struct(st, _) = self.dtype() else {
unreachable!()
};
st.field_info(field)
}
fn dtypes(&self) -> Vec<DType> {
let DType::Struct(st, _) = self.dtype() else {
unreachable!()
};
st.dtypes().collect()
}
fn nfields(&self) -> usize {
self.names().len()
}
fn maybe_null_field_by_idx(&self, idx: usize) -> Option<Array>;
fn maybe_null_field_by_name(&self, name: &str) -> Option<Array> {
let field_idx = self
.names()
.iter()
.position(|field_name| field_name.as_ref() == name);
field_idx.and_then(|field_idx| self.maybe_null_field_by_idx(field_idx))
}
fn maybe_null_field(&self, field: &Field) -> Option<Array> {
match field {
Field::Index(idx) => self.maybe_null_field_by_idx(*idx),
Field::Name(name) => self.maybe_null_field_by_name(name.as_ref()),
}
}
fn project(&self, projection: &[FieldName]) -> VortexResult<Array>;
}
pub trait ListArrayTrait {}
pub trait ExtensionArrayTrait: Deref<Target = Array> {
fn ext_dtype(&self) -> &Arc<ExtDType> {
let DType::Extension(ext_dtype) = self.dtype() else {
vortex_panic!("Expected ExtDType")
};
ext_dtype
}
fn storage_data(&self) -> Array;
}