use crate::spark::expression::literal::{LiteralType, Decimal, CalendarInterval, Array, Map, Struct};
use crate::spark::expression::Literal;
use crate::spark::DataType;
#[cfg(feature = "chrono")]
use chrono::{NaiveDate, NaiveDateTime};
pub trait ToLiteral {
fn to_literal(self) -> Literal;
}
impl Literal {
pub fn from_type(lit: LiteralType) -> Self {
Literal { literal_type: Some(lit) }
}
}
macro_rules! impl_to_literal {
($ty:ty => $variant:ident) => {
impl ToLiteral for $ty {
fn to_literal(self) -> Literal {
Literal::from_type(LiteralType::$variant(self))
}
}
};
}
impl_to_literal!(i32 => Integer);
impl_to_literal!(i64 => Long);
impl_to_literal!(f32 => Float);
impl_to_literal!(f64 => Double);
impl_to_literal!(bool => Boolean);
impl_to_literal!(String => String);
impl_to_literal!(Vec<u8> => Binary);
impl ToLiteral for i16 {
fn to_literal(self) -> Literal {
Literal::from_type(LiteralType::Short(self.into()))
}
}
impl ToLiteral for &str {
fn to_literal(self) -> Literal {
Literal::from_type(LiteralType::String(self.to_string()))
}
}
impl_to_literal!(Decimal => Decimal);
impl_to_literal!(CalendarInterval => CalendarInterval);
impl_to_literal!(Array => Array);
impl_to_literal!(Map => Map);
impl_to_literal!(Struct => Struct);
impl ToLiteral for Option<DataType> {
fn to_literal(self) -> Literal {
Literal::from_type(LiteralType::Null(self.unwrap_or_default()))
}
}
impl ToLiteral for Option<LiteralType> {
fn to_literal(self) -> Literal {
Literal::from_type(self.unwrap_or(LiteralType::Null(Default::default())))
}
}
#[cfg(feature = "chrono")]
impl ToLiteral for NaiveDate {
fn to_literal(self) -> Literal {
let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
let days_since_epoch = self.signed_duration_since(epoch).num_days() as i32;
Literal::from_type(LiteralType::Date(days_since_epoch))
}
}
#[cfg(feature = "chrono")]
impl ToLiteral for NaiveDateTime {
fn to_literal(self) -> Literal {
Literal::from_type(LiteralType::Timestamp(self.and_utc().timestamp_micros()))
}
}