#[cfg(test)]
mod test;
use std::sync::Arc;
use vortex_error::VortexError;
use vortex_error::vortex_bail;
use vortex_error::vortex_err;
use crate::ArrayRef;
use crate::DynArray;
use crate::IntoArray;
use crate::arrays::ExtensionArray;
use crate::arrays::ExtensionVTable;
use crate::dtype::DType;
use crate::dtype::extension::ExtDTypeRef;
use crate::extension::datetime::AnyTemporal;
use crate::extension::datetime::Date;
use crate::extension::datetime::TemporalMetadata;
use crate::extension::datetime::Time;
use crate::extension::datetime::TimeUnit;
use crate::extension::datetime::Timestamp;
#[derive(Clone, Debug)]
pub struct TemporalArray {
ext: ExtensionArray,
}
impl TemporalArray {
pub fn new_date(array: ArrayRef, time_unit: TimeUnit) -> Self {
Self {
ext: ExtensionArray::new(
Date::new(time_unit, array.dtype().nullability()).erased(),
array,
),
}
}
pub fn new_time(array: ArrayRef, time_unit: TimeUnit) -> Self {
Self {
ext: ExtensionArray::new(
Time::new(time_unit, array.dtype().nullability()).erased(),
array,
),
}
}
pub fn new_timestamp(
array: ArrayRef,
time_unit: TimeUnit,
time_zone: Option<Arc<str>>,
) -> Self {
Self {
ext: ExtensionArray::new(
Timestamp::new_with_tz(time_unit, time_zone, array.dtype().nullability()).erased(),
array,
),
}
}
}
impl TemporalArray {
pub fn temporal_values(&self) -> &ArrayRef {
self.ext.storage()
}
pub fn temporal_metadata(&self) -> TemporalMetadata<'_> {
self.ext.dtype().as_extension().metadata::<AnyTemporal>()
}
pub fn ext_dtype(&self) -> ExtDTypeRef {
self.ext.ext_dtype().clone()
}
pub fn dtype(&self) -> &DType {
self.ext.dtype()
}
}
impl AsRef<dyn DynArray> for TemporalArray {
fn as_ref(&self) -> &dyn DynArray {
self.ext.as_ref()
}
}
impl From<TemporalArray> for ArrayRef {
fn from(value: TemporalArray) -> Self {
value.ext.into_array()
}
}
impl IntoArray for TemporalArray {
fn into_array(self) -> ArrayRef {
self.into()
}
}
impl TryFrom<ArrayRef> for TemporalArray {
type Error = VortexError;
fn try_from(value: ArrayRef) -> Result<Self, Self::Error> {
let ext = value
.as_opt::<ExtensionVTable>()
.ok_or_else(|| vortex_err!("array must be an ExtensionArray"))?;
if !ext.ext_dtype().is::<AnyTemporal>() {
vortex_bail!(
"array extension dtype {} is not a temporal type",
ext.ext_dtype()
);
}
Ok(Self { ext: ext.clone() })
}
}
impl From<&TemporalArray> for ExtensionArray {
fn from(value: &TemporalArray) -> Self {
value.ext.clone()
}
}
impl From<TemporalArray> for ExtensionArray {
fn from(value: TemporalArray) -> Self {
value.ext
}
}
impl TryFrom<ExtensionArray> for TemporalArray {
type Error = VortexError;
fn try_from(ext: ExtensionArray) -> Result<Self, Self::Error> {
if !ext.ext_dtype().is::<AnyTemporal>() {
vortex_bail!(
"array extension dtype {} is not a temporal type",
ext.ext_dtype()
);
}
Ok(Self { ext })
}
}