Skip to main content

typed_arrow/bridge/
intervals.rs

1//! Interval types: `YearMonth`, `DayTime`, `MonthDayNano`.
2
3#[cfg(feature = "views")]
4use arrow_array::Array;
5use arrow_array::{
6    PrimitiveArray,
7    builder::PrimitiveBuilder,
8    types::{IntervalDayTimeType, IntervalMonthDayNanoType, IntervalYearMonthType},
9};
10use arrow_schema::{DataType, IntervalUnit};
11
12use super::ArrowBinding;
13#[cfg(feature = "views")]
14use super::ArrowBindingView;
15
16/// Interval with unit `YearMonth` (i32 months since epoch).
17#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
18pub struct IntervalYearMonth(i32);
19impl IntervalYearMonth {
20    /// Construct a new `YearMonth` interval value from months since epoch.
21    #[inline]
22    #[must_use]
23    pub fn new(value: i32) -> Self {
24        Self(value)
25    }
26    /// Return the months since epoch.
27    #[inline]
28    #[must_use]
29    pub fn value(&self) -> i32 {
30        self.0
31    }
32    /// Consume and return the months since epoch.
33    #[inline]
34    #[must_use]
35    pub fn into_value(self) -> i32 {
36        self.0
37    }
38}
39impl ArrowBinding for IntervalYearMonth {
40    type Builder = PrimitiveBuilder<IntervalYearMonthType>;
41    type Array = PrimitiveArray<IntervalYearMonthType>;
42    fn data_type() -> DataType {
43        DataType::Interval(IntervalUnit::YearMonth)
44    }
45    fn new_builder(capacity: usize) -> Self::Builder {
46        PrimitiveBuilder::<IntervalYearMonthType>::with_capacity(capacity)
47    }
48    fn append_value(b: &mut Self::Builder, v: &Self) {
49        b.append_value(v.0);
50    }
51    fn append_null(b: &mut Self::Builder) {
52        b.append_null();
53    }
54    fn finish(mut b: Self::Builder) -> Self::Array {
55        b.finish()
56    }
57}
58
59#[cfg(feature = "views")]
60impl ArrowBindingView for IntervalYearMonth {
61    type Array = PrimitiveArray<IntervalYearMonthType>;
62    type View<'a> = IntervalYearMonth;
63
64    fn get_view(
65        array: &Self::Array,
66        index: usize,
67    ) -> Result<Self::View<'_>, crate::schema::ViewAccessError> {
68        if index >= array.len() {
69            return Err(crate::schema::ViewAccessError::OutOfBounds {
70                index,
71                len: array.len(),
72                field_name: None,
73            });
74        }
75        if array.is_null(index) {
76            return Err(crate::schema::ViewAccessError::UnexpectedNull {
77                index,
78                field_name: None,
79            });
80        }
81        Ok(IntervalYearMonth::new(array.value(index)))
82    }
83}
84
85/// Interval with unit `DayTime` (packed days and milliseconds).
86#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
87pub struct IntervalDayTime(arrow_array::types::IntervalDayTime);
88impl IntervalDayTime {
89    /// Construct a new `DayTime` interval from the native Arrow struct.
90    #[inline]
91    #[must_use]
92    pub fn new(value: arrow_array::types::IntervalDayTime) -> Self {
93        Self(value)
94    }
95    /// Return the underlying Arrow `DayTime` interval value.
96    #[inline]
97    #[must_use]
98    pub fn value(&self) -> arrow_array::types::IntervalDayTime {
99        self.0
100    }
101    /// Consume and return the underlying Arrow `DayTime` interval value.
102    #[inline]
103    #[must_use]
104    pub fn into_value(self) -> arrow_array::types::IntervalDayTime {
105        self.0
106    }
107}
108impl ArrowBinding for IntervalDayTime {
109    type Builder = PrimitiveBuilder<IntervalDayTimeType>;
110    type Array = PrimitiveArray<IntervalDayTimeType>;
111    fn data_type() -> DataType {
112        DataType::Interval(IntervalUnit::DayTime)
113    }
114    fn new_builder(capacity: usize) -> Self::Builder {
115        PrimitiveBuilder::<IntervalDayTimeType>::with_capacity(capacity)
116    }
117    fn append_value(b: &mut Self::Builder, v: &Self) {
118        b.append_value(v.0);
119    }
120    fn append_null(b: &mut Self::Builder) {
121        b.append_null();
122    }
123    fn finish(mut b: Self::Builder) -> Self::Array {
124        b.finish()
125    }
126}
127
128#[cfg(feature = "views")]
129impl ArrowBindingView for IntervalDayTime {
130    type Array = PrimitiveArray<IntervalDayTimeType>;
131    type View<'a> = IntervalDayTime;
132
133    fn get_view(
134        array: &Self::Array,
135        index: usize,
136    ) -> Result<Self::View<'_>, crate::schema::ViewAccessError> {
137        if index >= array.len() {
138            return Err(crate::schema::ViewAccessError::OutOfBounds {
139                index,
140                len: array.len(),
141                field_name: None,
142            });
143        }
144        if array.is_null(index) {
145            return Err(crate::schema::ViewAccessError::UnexpectedNull {
146                index,
147                field_name: None,
148            });
149        }
150        Ok(IntervalDayTime::new(array.value(index)))
151    }
152}
153
154/// Interval with unit `MonthDayNano` (packed months, days, and nanoseconds).
155#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
156pub struct IntervalMonthDayNano(arrow_array::types::IntervalMonthDayNano);
157impl IntervalMonthDayNano {
158    /// Construct a new `MonthDayNano` interval from the native Arrow struct.
159    #[inline]
160    #[must_use]
161    pub fn new(value: arrow_array::types::IntervalMonthDayNano) -> Self {
162        Self(value)
163    }
164    /// Return the underlying Arrow `MonthDayNano` interval value.
165    #[inline]
166    #[must_use]
167    pub fn value(&self) -> arrow_array::types::IntervalMonthDayNano {
168        self.0
169    }
170    /// Consume and return the underlying Arrow `MonthDayNano` interval value.
171    #[inline]
172    #[must_use]
173    pub fn into_value(self) -> arrow_array::types::IntervalMonthDayNano {
174        self.0
175    }
176}
177impl ArrowBinding for IntervalMonthDayNano {
178    type Builder = PrimitiveBuilder<IntervalMonthDayNanoType>;
179    type Array = PrimitiveArray<IntervalMonthDayNanoType>;
180    fn data_type() -> DataType {
181        DataType::Interval(IntervalUnit::MonthDayNano)
182    }
183    fn new_builder(capacity: usize) -> Self::Builder {
184        PrimitiveBuilder::<IntervalMonthDayNanoType>::with_capacity(capacity)
185    }
186    fn append_value(b: &mut Self::Builder, v: &Self) {
187        b.append_value(v.0);
188    }
189    fn append_null(b: &mut Self::Builder) {
190        b.append_null();
191    }
192    fn finish(mut b: Self::Builder) -> Self::Array {
193        b.finish()
194    }
195}
196
197#[cfg(feature = "views")]
198impl ArrowBindingView for IntervalMonthDayNano {
199    type Array = PrimitiveArray<IntervalMonthDayNanoType>;
200    type View<'a> = IntervalMonthDayNano;
201
202    fn get_view(
203        array: &Self::Array,
204        index: usize,
205    ) -> Result<Self::View<'_>, crate::schema::ViewAccessError> {
206        if index >= array.len() {
207            return Err(crate::schema::ViewAccessError::OutOfBounds {
208                index,
209                len: array.len(),
210                field_name: None,
211            });
212        }
213        if array.is_null(index) {
214            return Err(crate::schema::ViewAccessError::UnexpectedNull {
215                index,
216                field_name: None,
217            });
218        }
219        Ok(IntervalMonthDayNano::new(array.value(index)))
220    }
221}