diff --git a/examples/parquet.rs b/examples/parquet.rs index 62c64a6..b779d94 100644 --- a/examples/parquet.rs +++ b/examples/parquet.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use chrono::{DateTime, NaiveTime, Utc}; +use chrono::{DateTime, NaiveDate, NaiveTime, TimeDelta, Utc}; #[rustversion::attr(nightly, allow(non_local_definitions))] fn main() { @@ -32,6 +32,8 @@ fn main() { j: DateTime, k: NaiveTime, l: Option>>, + m: NaiveDate, + n: TimeDelta, } let input = [ Foo { @@ -50,6 +52,8 @@ fn main() { "a".to_string(), vec![1, 2, 3, 4, 42], )])), + m: NaiveDate::MAX, + n: TimeDelta::max_value(), }, Foo { a: 42, @@ -64,6 +68,8 @@ fn main() { j: Utc::now(), k: Utc::now().time(), l: None, + m: NaiveDate::MIN, + n: TimeDelta::min_value(), }, ]; diff --git a/src/logical/chrono.rs b/src/logical/chrono.rs index 66125e3..c8bcb68 100644 --- a/src/logical/chrono.rs +++ b/src/logical/chrono.rs @@ -1,4 +1,4 @@ -use chrono::{DateTime, NaiveDateTime, NaiveTime, Timelike, Utc}; +use chrono::{DateTime, Datelike, NaiveDate, NaiveDateTime, NaiveTime, TimeDelta, Timelike, Utc}; use crate::{ array::{ArrayType, UnionType}, @@ -60,6 +60,32 @@ impl LogicalArrayType for NaiveDateTime { pub type NaiveDateTimeArray = LogicalArray; +impl ArrayType for NaiveDate { + type Array = + LogicalArray; +} + +impl ArrayType for Option { + type Array = + LogicalArray; +} + +impl LogicalArrayType for NaiveDate { + type ArrayType = i32; + + fn from_array_type(item: Self::ArrayType) -> Self { + NaiveDate::from_num_days_from_ce_opt(item).expect("out of range") + } + + fn into_array_type(self) -> Self::ArrayType { + self.num_days_from_ce() + } +} + +/// An array for [`NaiveDate`] items. +pub type NaiveDateArray = + LogicalArray; + impl ArrayType for NaiveTime { type Array = LogicalArray; @@ -94,13 +120,53 @@ impl LogicalArrayType for NaiveTime { pub type NaiveTimeArray = LogicalArray; +impl ArrayType for TimeDelta { + type Array = + LogicalArray; +} + +impl ArrayType for Option { + type Array = + LogicalArray; +} + +impl LogicalArrayType for TimeDelta { + type ArrayType = i64; + + fn from_array_type(item: Self::ArrayType) -> Self { + Self::nanoseconds(item) + } + + fn into_array_type(self) -> Self::ArrayType { + self.num_nanoseconds().expect("out of range") + } +} + +/// An array for [`TimeDelta`] items. +pub type TimeDeltaArray = + LogicalArray; + #[cfg(test)] mod tests { use super::*; use crate::Length; #[test] - fn round_trip() { + fn round_trip_naivedate() { + for value in [ + NaiveDate::from_yo_opt(2024, 7) + .expect("out of range") + .num_days_from_ce(), + NaiveDate::from_yo_opt(2020, 6) + .expect("out of range") + .num_days_from_ce(), + ] { + assert_eq!(NaiveDate::from_array_type(value).into_array_type(), value); + } + } + + #[test] + fn round_trip_naivetime() { for value in [ 0, 1234, @@ -111,6 +177,18 @@ mod tests { } } + #[test] + fn round_trip_timedelta() { + for value in [ + 0, + 1234, + 1234 * NANO_SECONDS, + 86_398 * NANO_SECONDS + 1_999_999_999, + ] { + assert_eq!(TimeDelta::nanoseconds(value).into_array_type(), value); + } + } + #[test] fn from_iter() { let array = [DateTime::::UNIX_EPOCH, DateTime::::UNIX_EPOCH]