use vortex_error::VortexExpect;
use vortex_error::VortexResult;
use vortex_error::vortex_ensure;
use vortex_error::vortex_err;
use crate::DType;
use crate::ExtDType;
use crate::Nullability;
use crate::PType;
use crate::datetime::TimeUnit;
use crate::extension::ExtDTypeVTable;
use crate::extension::ExtID;
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct Time;
impl Time {
pub fn try_new(time_unit: TimeUnit, nullability: Nullability) -> VortexResult<ExtDType<Self>> {
let ptype = time_ptype(&time_unit)
.ok_or_else(|| vortex_err!("Time type does not support time unit {}", time_unit))?;
ExtDType::try_new(time_unit, DType::Primitive(ptype, nullability))
}
pub fn new(time_unit: TimeUnit, nullability: Nullability) -> ExtDType<Self> {
Self::try_new(time_unit, nullability).vortex_expect("failed to create time dtype")
}
}
impl ExtDTypeVTable for Time {
type Metadata = TimeUnit;
fn id(&self) -> ExtID {
ExtID::new_ref("vortex.time")
}
fn serialize(&self, metadata: &Self::Metadata) -> VortexResult<Vec<u8>> {
Ok(vec![u8::from(*metadata)])
}
fn deserialize(&self, data: &[u8]) -> VortexResult<Self::Metadata> {
let tag = data[0];
TimeUnit::try_from(tag)
}
fn validate_dtype(&self, metadata: &Self::Metadata, storage_dtype: &DType) -> VortexResult<()> {
let ptype = time_ptype(metadata)
.ok_or_else(|| vortex_err!("Time type does not support time unit {}", metadata))?;
vortex_ensure!(
storage_dtype.as_ptype() == ptype,
"Time storage dtype for {} must be {}",
metadata,
ptype
);
Ok(())
}
}
fn time_ptype(time_unit: &TimeUnit) -> Option<PType> {
Some(match time_unit {
TimeUnit::Nanoseconds | TimeUnit::Microseconds => PType::I64,
TimeUnit::Milliseconds | TimeUnit::Seconds => PType::I32,
TimeUnit::Days => return None,
})
}