use vortex_error::VortexError;
use vortex_error::VortexExpect;
use vortex_error::VortexResult;
use vortex_error::vortex_err;
use crate::dtype::DType;
use crate::dtype::NativePType;
use crate::dtype::Nullability;
use crate::dtype::PType;
use crate::dtype::half::f16;
use crate::scalar::PValue;
use crate::scalar::PrimitiveScalar;
use crate::scalar::Scalar;
use crate::scalar::ScalarValue;
impl From<PrimitiveScalar<'_>> for Scalar {
fn from(ps: PrimitiveScalar<'_>) -> Self {
unsafe {
Scalar::new_unchecked(ps.dtype().clone(), ps.pvalue().map(ScalarValue::Primitive))
}
}
}
impl From<PValue> for ScalarValue {
fn from(value: PValue) -> Self {
ScalarValue::Primitive(value)
}
}
macro_rules! primitive_scalar {
($T:ty) => {
impl TryFrom<&ScalarValue> for $T {
type Error = VortexError;
fn try_from(value: &ScalarValue) -> VortexResult<Self> {
value.as_primitive().cast::<$T>()
}
}
impl TryFrom<&Scalar> for $T {
type Error = VortexError;
fn try_from(value: &Scalar) -> VortexResult<Self> {
match value.value() {
Some(ScalarValue::Primitive(pv)) => pv.cast::<$T>(),
Some(_) => Err(vortex_err!(
"Expected primitive scalar, found {}",
value.dtype()
)),
None => Err(vortex_err!("Can't extract present value from null scalar")),
}
}
}
impl TryFrom<&Scalar> for Option<$T> {
type Error = VortexError;
fn try_from(value: &Scalar) -> VortexResult<Self> {
let primitive_scalar = PrimitiveScalar::try_new(value.dtype(), value.value())?;
primitive_scalar.try_typed_value::<$T>()
}
}
impl From<$T> for ScalarValue {
fn from(value: $T) -> Self {
ScalarValue::Primitive(value.into())
}
}
impl From<$T> for Scalar {
fn from(value: $T) -> Self {
Scalar::try_new(
DType::Primitive(<$T>::PTYPE, Nullability::NonNullable),
Some(ScalarValue::Primitive(value.into())),
)
.vortex_expect(
"somehow unable to construct a primitive `Scalar` from a native type",
)
}
}
impl From<Option<$T>> for Scalar {
fn from(value: Option<$T>) -> Self {
Scalar::try_new(
DType::Primitive(<$T>::PTYPE, Nullability::Nullable),
value.map(|value| ScalarValue::Primitive(value.into())),
)
.vortex_expect(
"somehow unable to construct a primitive `Scalar` from a native type",
)
}
}
};
}
primitive_scalar!(u8);
primitive_scalar!(u16);
primitive_scalar!(u32);
primitive_scalar!(u64);
primitive_scalar!(i8);
primitive_scalar!(i16);
primitive_scalar!(i32);
primitive_scalar!(i64);
primitive_scalar!(f16);
primitive_scalar!(f32);
primitive_scalar!(f64);
impl TryFrom<&ScalarValue> for usize {
type Error = VortexError;
fn try_from(value: &ScalarValue) -> VortexResult<Self> {
let val = value.as_primitive().cast::<u64>()?;
Ok(usize::try_from(val)?)
}
}
impl TryFrom<&Scalar> for usize {
type Error = VortexError;
fn try_from(value: &Scalar) -> Result<Self, Self::Error> {
let prim_scalar = value
.as_primitive_opt()
.ok_or_else(|| vortex_err!("Expected primitive scalar, found {}", value.dtype()))?;
let prim = prim_scalar
.as_::<u64>()
.ok_or_else(|| vortex_err!("cannot convert Null to usize"))?;
Ok(usize::try_from(prim)?)
}
}
impl TryFrom<&Scalar> for Option<usize> {
type Error = VortexError;
fn try_from(value: &Scalar) -> Result<Self, Self::Error> {
let prim_scalar = value
.as_primitive_opt()
.ok_or_else(|| vortex_err!("Expected primitive scalar, found {}", value.dtype()))?;
Ok(prim_scalar.as_::<u64>().map(usize::try_from).transpose()?)
}
}
impl From<usize> for ScalarValue {
fn from(value: usize) -> Self {
ScalarValue::Primitive((value as u64).into())
}
}
impl From<usize> for Scalar {
fn from(value: usize) -> Self {
Scalar::try_new(
DType::Primitive(PType::U64, Nullability::NonNullable),
Some(ScalarValue::Primitive((value as u64).into())),
)
.vortex_expect("somehow unable to construct a primitive `Scalar` from a native type")
}
}
impl From<Option<usize>> for Scalar {
fn from(value: Option<usize>) -> Self {
Scalar::try_new(
DType::Primitive(PType::U64, Nullability::Nullable),
value.map(|value| ScalarValue::Primitive((value as u64).into())),
)
.vortex_expect("somehow unable to construct a primitive `Scalar` from a native type")
}
}