use crate::compute::kernels::cast_utils::string_to_timestamp_nanos;
use crate::datatypes::*;
pub(crate) trait Parser: ArrowPrimitiveType {
fn parse(string: &str) -> Option<Self::Native> {
string.parse::<Self::Native>().ok()
}
fn parse_formatted(string: &str, _format: &str) -> Option<Self::Native> {
Self::parse(string)
}
}
impl Parser for Float32Type {
fn parse(string: &str) -> Option<f32> {
lexical_core::parse(string.as_bytes()).ok()
}
}
impl Parser for Float64Type {
fn parse(string: &str) -> Option<f64> {
lexical_core::parse(string.as_bytes()).ok()
}
}
impl Parser for UInt64Type {}
impl Parser for UInt32Type {}
impl Parser for UInt16Type {}
impl Parser for UInt8Type {}
impl Parser for Int64Type {}
impl Parser for Int32Type {}
impl Parser for Int16Type {}
impl Parser for Int8Type {}
impl Parser for TimestampNanosecondType {
fn parse(string: &str) -> Option<i64> {
string_to_timestamp_nanos(string).ok()
}
}
impl Parser for TimestampMicrosecondType {
fn parse(string: &str) -> Option<i64> {
let nanos = string_to_timestamp_nanos(string).ok();
nanos.map(|x| x / 1000)
}
}
impl Parser for TimestampMillisecondType {
fn parse(string: &str) -> Option<i64> {
let nanos = string_to_timestamp_nanos(string).ok();
nanos.map(|x| x / 1_000_000)
}
}
impl Parser for TimestampSecondType {
fn parse(string: &str) -> Option<i64> {
let nanos = string_to_timestamp_nanos(string).ok();
nanos.map(|x| x / 1_000_000_000)
}
}
impl Parser for Time64NanosecondType {}
impl Parser for Time64MicrosecondType {}
impl Parser for Time32MillisecondType {}
impl Parser for Time32SecondType {}
const EPOCH_DAYS_FROM_CE: i32 = 719_163;
impl Parser for Date32Type {
fn parse(string: &str) -> Option<i32> {
use chrono::Datelike;
let date = string.parse::<chrono::NaiveDate>().ok()?;
Self::Native::from_i32(date.num_days_from_ce() - EPOCH_DAYS_FROM_CE)
}
fn parse_formatted(string: &str, format: &str) -> Option<i32> {
use chrono::Datelike;
let date = chrono::NaiveDate::parse_from_str(string, format).ok()?;
Self::Native::from_i32(date.num_days_from_ce() - EPOCH_DAYS_FROM_CE)
}
}
impl Parser for Date64Type {
fn parse(string: &str) -> Option<i64> {
let date_time = string.parse::<chrono::NaiveDateTime>().ok()?;
Self::Native::from_i64(date_time.timestamp_millis())
}
fn parse_formatted(string: &str, format: &str) -> Option<i64> {
use chrono::format::Fixed;
use chrono::format::StrftimeItems;
let fmt = StrftimeItems::new(format);
let has_zone = fmt.into_iter().any(|item| match item {
chrono::format::Item::Fixed(fixed_item) => matches!(
fixed_item,
Fixed::RFC2822
| Fixed::RFC3339
| Fixed::TimezoneName
| Fixed::TimezoneOffsetColon
| Fixed::TimezoneOffsetColonZ
| Fixed::TimezoneOffset
| Fixed::TimezoneOffsetZ
),
_ => false,
});
if has_zone {
let date_time = chrono::DateTime::parse_from_str(string, format).ok()?;
Self::Native::from_i64(date_time.timestamp_millis())
} else {
let date_time = chrono::NaiveDateTime::parse_from_str(string, format).ok()?;
Self::Native::from_i64(date_time.timestamp_millis())
}
}
}