use std::fmt;
use std::str::FromStr;
use super::data_type_parse_error::DataTypeParseError;
use serde::{
Deserialize,
Serialize,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum DataType {
Bool,
Char,
Int8,
Int16,
Int32,
Int64,
Int128,
UInt8,
UInt16,
UInt32,
UInt64,
UInt128,
Float32,
Float64,
String,
Date,
Time,
DateTime,
Instant,
BigInteger,
BigDecimal,
Duration,
Url,
StringMap,
Json,
}
impl fmt::Display for DataType {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(self.as_str())
}
}
macro_rules! define_data_type_names {
($( $variant:ident => $name:literal ),+ $(,)?) => {
impl FromStr for DataType {
type Err = DataTypeParseError;
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value.to_ascii_lowercase().as_str() {
$( $name => Ok(DataType::$variant), )+
_ => Err(DataTypeParseError::new(value)),
}
}
}
impl DataType {
pub const ALL: [DataType; 25] = [$( DataType::$variant, )+];
#[inline]
pub const fn as_str(self) -> &'static str {
match self {
$( DataType::$variant => $name, )+
}
}
}
};
}
define_data_type_names! {
Bool => "bool",
Char => "char",
Int8 => "int8",
Int16 => "int16",
Int32 => "int32",
Int64 => "int64",
Int128 => "int128",
UInt8 => "uint8",
UInt16 => "uint16",
UInt32 => "uint32",
UInt64 => "uint64",
UInt128 => "uint128",
Float32 => "float32",
Float64 => "float64",
String => "string",
Date => "date",
Time => "time",
DateTime => "datetime",
Instant => "instant",
BigInteger => "biginteger",
BigDecimal => "bigdecimal",
Duration => "duration",
Url => "url",
StringMap => "stringmap",
Json => "json",
}
impl DataType {
#[inline]
pub const fn is_numeric(self) -> bool {
self.is_integer() || self.is_float() || self.is_big_number()
}
#[inline]
pub const fn is_integer(self) -> bool {
self.is_signed_integer() || self.is_unsigned_integer()
}
#[inline]
pub const fn is_signed_integer(self) -> bool {
matches!(
self,
DataType::Int8
| DataType::Int16
| DataType::Int32
| DataType::Int64
| DataType::Int128
)
}
#[inline]
pub const fn is_unsigned_integer(self) -> bool {
matches!(
self,
DataType::UInt8
| DataType::UInt16
| DataType::UInt32
| DataType::UInt64
| DataType::UInt128
)
}
#[inline]
pub const fn is_float(self) -> bool {
matches!(self, DataType::Float32 | DataType::Float64)
}
#[inline]
pub const fn is_big_number(self) -> bool {
matches!(self, DataType::BigInteger | DataType::BigDecimal)
}
}