use std::cmp::Ordering;
use std::fmt::Debug;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum DataType {
Null,
Bool,
Int8,
Int16,
Int32,
Int64,
Int128,
UInt8,
UInt16,
UInt32,
UInt64,
UInt128,
Float32,
Float64,
String,
List(Box<DataType>),
}
impl DataType {
pub fn is_float(&self) -> bool {
matches!(self, DataType::Float32 | DataType::Float64)
}
pub fn is_integer(&self) -> bool {
matches!(
self,
DataType::Int8 | DataType::Int16 | DataType::Int32 | DataType::Int64 | DataType::Int128 |
DataType::UInt8 | DataType::UInt16 | DataType::UInt32 | DataType::UInt64 | DataType::UInt128
)
}
pub fn is_numeric(&self) -> bool {
matches!(
self,
DataType::Int8 | DataType::Int16 | DataType::Int32 | DataType::Int64 |
DataType::UInt8 | DataType::UInt16 | DataType::UInt32 | DataType::UInt64 |
DataType::Float32 | DataType::Float64
)
}
}
impl Ord for DataType {
fn cmp(&self, other: &Self) -> Ordering {
fn order_index(dt: &DataType) -> i32 {
match dt {
DataType::Null => 0,
DataType::Bool => 1,
DataType::Int8 => 10,
DataType::Int16 => 11,
DataType::Int32 => 12,
DataType::Int64 => 13,
DataType::Int128 => 14,
DataType::UInt8 => 20,
DataType::UInt16 => 21,
DataType::UInt32 => 22,
DataType::UInt64 => 23,
DataType::UInt128 => 24,
DataType::Float32 => 30,
DataType::Float64 => 31,
DataType::String => 40,
DataType::List(_) => 100,
}
}
match order_index(self).cmp(&order_index(other)) {
Ordering::Equal => {
match (self, other) {
(DataType::List(a), DataType::List(b)) => a.cmp(b),
_ => Ordering::Equal,
}
}
order => order,
}
}
}
impl PartialOrd for DataType {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
pub trait DataTypeTrait: Debug + Clone + Send + Sync + 'static {
const DTYPE: DataType;
fn as_dtype(&self) -> DataType;
}
macro_rules! impl_datatype_trait {
($prim_type: ty, $dtype_variant: ident) => {
impl DataTypeTrait for $prim_type where $prim_type: Debug + Clone {
const DTYPE: DataType = DataType::$dtype_variant;
fn as_dtype(&self) -> DataType {
Self::DTYPE
}
}
};
}
impl_datatype_trait!(i8, Int8);
impl_datatype_trait!(i16, Int16);
impl_datatype_trait!(i32, Int32);
impl_datatype_trait!(i64, Int64);
impl_datatype_trait!(u8, UInt8);
impl_datatype_trait!(u16, UInt16);
impl_datatype_trait!(u32, UInt32);
impl_datatype_trait!(u64, UInt64);
impl_datatype_trait!(f32, Float32);
impl_datatype_trait!(f64, Float64);
impl_datatype_trait!(bool, Bool);
impl DataTypeTrait for String {
const DTYPE: DataType = DataType::String;
fn as_dtype(&self) -> DataType {
Self::DTYPE
}
}