vortex_array/compute/
to_arrow.rsuse arrow_array::{Array as ArrowArray, ArrayRef};
use arrow_schema::DataType;
use vortex_error::{vortex_err, VortexError, VortexExpect, VortexResult};
use crate::arrow::infer_data_type;
use crate::encoding::Encoding;
use crate::{Array, IntoArray, IntoCanonical};
pub trait ToArrowFn<A> {
fn preferred_arrow_data_type(&self, _array: &A) -> VortexResult<Option<DataType>> {
Ok(None)
}
fn to_arrow(&self, array: &A, data_type: &DataType) -> VortexResult<Option<ArrayRef>>;
}
impl<E: Encoding> ToArrowFn<Array> for E
where
E: ToArrowFn<E::Array>,
for<'a> &'a E::Array: TryFrom<&'a Array, Error = VortexError>,
{
fn preferred_arrow_data_type(&self, array: &Array) -> VortexResult<Option<DataType>> {
let (array_ref, encoding) = array.try_downcast_ref::<E>()?;
ToArrowFn::preferred_arrow_data_type(encoding, array_ref)
}
fn to_arrow(&self, array: &Array, data_type: &DataType) -> VortexResult<Option<ArrayRef>> {
let (array_ref, encoding) = array.try_downcast_ref::<E>()?;
ToArrowFn::to_arrow(encoding, array_ref, data_type)
}
}
pub fn preferred_arrow_data_type<A: AsRef<Array>>(array: A) -> VortexResult<DataType> {
let array = array.as_ref();
if let Some(result) = array
.vtable()
.to_arrow_fn()
.and_then(|f| f.preferred_arrow_data_type(array).transpose())
.transpose()?
{
return Ok(result);
}
infer_data_type(array.dtype())
}
pub fn to_arrow<A: AsRef<Array>>(array: A, data_type: &DataType) -> VortexResult<ArrayRef> {
let array = array.as_ref();
if let Some(result) = array
.vtable()
.to_arrow_fn()
.and_then(|f| f.to_arrow(array, data_type).transpose())
.transpose()?
{
assert_eq!(
result.data_type(),
data_type,
"ToArrowFn returned wrong data type"
);
return Ok(result);
}
let array = array.clone().into_canonical()?.into_array();
array
.vtable()
.to_arrow_fn()
.vortex_expect("Canonical encodings must implement ToArrowFn")
.to_arrow(&array, data_type)?
.ok_or_else(|| {
vortex_err!(
"Failed to convert array {} to Arrow {}",
array.encoding(),
data_type
)
})
}