1717
1818//! Module for transforming a typed arrow `Array` to `VariantArray`.
1919
20- use arrow:: datatypes:: {
21- self , ArrowPrimitiveType , ArrowTimestampType , Date32Type , TimestampMicrosecondType ,
22- TimestampNanosecondType ,
23- } ;
20+ use arrow:: datatypes:: { self , ArrowPrimitiveType , ArrowTimestampType , Date32Type } ;
2421use parquet_variant:: Variant ;
2522
2623/// Options for controlling the behavior of `cast_to_variant_with_options`.
@@ -41,6 +38,13 @@ pub(crate) trait PrimitiveFromVariant: ArrowPrimitiveType {
4138 fn from_variant ( variant : & Variant < ' _ , ' _ > ) -> Option < Self :: Native > ;
4239}
4340
41+ /// Extension trait for Arrow timestamp types that can extract their native value from a Variant
42+ /// We can't use [`PrimitiveFromVariant`] directly because we might need to use methods that
43+ /// are only available on [`ArrowTimestampType`] (such as with_timezone_opt)
44+ pub ( crate ) trait TimestampFromVariant : ArrowTimestampType {
45+ fn from_variant ( variant : & Variant < ' _ , ' _ > ) -> Option < Self :: Native > ;
46+ }
47+
4448/// Macro to generate PrimitiveFromVariant implementations for Arrow primitive types
4549macro_rules! impl_primitive_from_variant {
4650 ( $arrow_type: ty, $variant_method: ident $( , $cast_fn: expr) ?) => {
@@ -52,6 +56,18 @@ macro_rules! impl_primitive_from_variant {
5256 }
5357 }
5458 } ;
59+ ( $arrow_type: ty $( , $variant_method: ident => $cast_fn: expr ) + ) => {
60+ impl TimestampFromVariant for $arrow_type {
61+ fn from_variant( variant: & Variant <' _, ' _>) -> Option <Self :: Native > {
62+ $(
63+ if let Some ( value) = variant. $variant_method( ) {
64+ return Some ( $cast_fn( value) ) ;
65+ }
66+ ) +
67+ None
68+ }
69+ }
70+ } ;
5571}
5672
5773impl_primitive_from_variant ! ( datatypes:: Int32Type , as_int32) ;
@@ -70,41 +86,13 @@ impl_primitive_from_variant!(
7086 as_naive_date,
7187 Date32Type :: from_naive_date
7288) ;
73-
74- pub ( crate ) trait TimestampFromVariant : ArrowTimestampType {
75- fn from_variant ( variant : & Variant < ' _ , ' _ > ) -> Option < Self :: Native > ;
76- }
77-
78- macro_rules! impl_timestamp_from_variant {
79- ( $timestamp_type: ty,
80- $( $variant_pattern: pat => $conversion: expr ) ,+ $( , ) ?
81- ) => {
82- impl TimestampFromVariant for $timestamp_type {
83- fn from_variant( variant: & Variant <' _, ' _>) -> Option <Self :: Native > {
84- match variant {
85- $(
86- $variant_pattern => $conversion,
87- ) +
88- _ => None ,
89- }
90- }
91- }
92- } ;
93- }
94-
95- impl_timestamp_from_variant ! (
96- TimestampMicrosecondType ,
97- Variant :: TimestampMicros ( t) => Some ( t. timestamp_micros( ) ) ,
98- Variant :: TimestampNtzMicros ( t) => Some ( t. and_utc( ) . timestamp_micros( ) ) ,
99- ) ;
100-
101- impl_timestamp_from_variant ! (
102- TimestampNanosecondType ,
103- Variant :: TimestampMicros ( t) => Some ( t. timestamp_micros( ) ) . map( |t| t * 1000 ) ,
104- Variant :: TimestampNtzMicros ( t) => Some ( t. and_utc( ) . timestamp_micros( ) ) . map( |t| t * 1000 ) ,
105- Variant :: TimestampNanos ( t) => t. timestamp_nanos_opt( ) ,
106- Variant :: TimestampNtzNanos ( t) => t. and_utc( ) . timestamp_nanos_opt( ) ,
107- ) ;
89+ impl_primitive_from_variant ! (
90+ datatypes:: TimestampMicrosecondType ,
91+ as_timestamp_micros => |t| t) ;
92+ impl_primitive_from_variant ! (
93+ datatypes:: TimestampNanosecondType ,
94+ as_timestamp_micros => |t| 1000 * t,
95+ as_timestamp_nanos => |t| t) ;
10896
10997/// Convert the value at a specific index in the given array into a `Variant`.
11098macro_rules! non_generic_conversion_single_value {
0 commit comments