use std::fmt;
use arrow::datatypes::{DataType, IntervalUnit, TimeUnit};
#[derive(Debug, Clone, PartialEq)]
pub enum LiteralValue {
Boolean(bool),
Int8(i8),
Int16(i16),
Int32(i32),
Int64(i64),
UInt8(u8),
UInt16(u16),
UInt32(u32),
UInt64(u64),
Float32(f32),
Float64(f64),
Utf8(String),
LargeUtf8(String),
Decimal128 {
raw: i128,
precision: u8,
scale: i8,
},
Date32(i32),
Date64(i64),
Time32 {
raw: i32,
unit: TimeUnit,
},
Time64 {
raw: i64,
unit: TimeUnit,
},
Timestamp {
raw: i64,
unit: TimeUnit,
},
Duration {
raw: i64,
unit: TimeUnit,
},
IntervalMonthDayNano {
months: i32,
days: i32,
nanoseconds: i64,
},
Null(DataType),
}
impl LiteralValue {
pub fn data_type(&self) -> DataType {
match self {
Self::Boolean(_) => DataType::Boolean,
Self::Int8(_) => DataType::Int8,
Self::Int16(_) => DataType::Int16,
Self::Int32(_) => DataType::Int32,
Self::Int64(_) => DataType::Int64,
Self::UInt8(_) => DataType::UInt8,
Self::UInt16(_) => DataType::UInt16,
Self::UInt32(_) => DataType::UInt32,
Self::UInt64(_) => DataType::UInt64,
Self::Float32(_) => DataType::Float32,
Self::Float64(_) => DataType::Float64,
Self::Utf8(_) => DataType::Utf8,
Self::LargeUtf8(_) => DataType::LargeUtf8,
Self::Decimal128 { precision, scale, .. } => DataType::Decimal128(*precision, *scale),
Self::Date32(_) => DataType::Date32,
Self::Date64(_) => DataType::Date64,
Self::Time32 { unit, .. } => DataType::Time32(*unit),
Self::Time64 { unit, .. } => DataType::Time64(*unit),
Self::Timestamp { unit, .. } => DataType::Timestamp(*unit, None),
Self::Duration { unit, .. } => DataType::Duration(*unit),
Self::IntervalMonthDayNano { .. } => DataType::Interval(IntervalUnit::MonthDayNano),
Self::Null(data_type) => data_type.clone(),
}
}
pub(crate) fn integer_zero(data_type: &DataType) -> Option<Self> {
match data_type {
DataType::Int8 => Some(Self::Int8(0)),
DataType::Int16 => Some(Self::Int16(0)),
DataType::Int32 => Some(Self::Int32(0)),
DataType::Int64 => Some(Self::Int64(0)),
DataType::UInt8 => Some(Self::UInt8(0)),
DataType::UInt16 => Some(Self::UInt16(0)),
DataType::UInt32 => Some(Self::UInt32(0)),
DataType::UInt64 => Some(Self::UInt64(0)),
_ => None,
}
}
}
impl fmt::Display for LiteralValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Boolean(value) => write!(f, "{value}"),
Self::Int8(value) => write!(f, "{value}"),
Self::Int16(value) => write!(f, "{value}"),
Self::Int32(value) => write!(f, "{value}"),
Self::Int64(value) => write!(f, "{value}"),
Self::UInt8(value) => write!(f, "{value}"),
Self::UInt16(value) => write!(f, "{value}"),
Self::UInt32(value) => write!(f, "{value}"),
Self::UInt64(value) => write!(f, "{value}"),
Self::Float32(value) => write!(f, "{value}"),
Self::Float64(value) => write!(f, "{value}"),
Self::Utf8(value) | Self::LargeUtf8(value) => write!(f, "{value:?}"),
Self::Decimal128 { raw, precision, scale } => {
write!(f, "DECIMAL128({raw}, precision={precision}, scale={scale})")
},
Self::Date32(value) => write!(f, "DATE32({value})"),
Self::Date64(value) => write!(f, "DATE64({value})"),
Self::Time32 { raw, unit } => write!(f, "TIME32({raw}, {unit:?})"),
Self::Time64 { raw, unit } => write!(f, "TIME64({raw}, {unit:?})"),
Self::Timestamp { raw, unit } => write!(f, "TIMESTAMP({raw}, {unit:?})"),
Self::Duration { raw, unit } => write!(f, "DURATION({raw}, {unit:?})"),
Self::IntervalMonthDayNano { months, days, nanoseconds } => {
write!(f, "INTERVAL(months={months}, days={days}, nanoseconds={nanoseconds})")
},
Self::Null(data_type) => write!(f, "NULL::{data_type}"),
}
}
}