typed_arrow/bridge/
intervals.rs

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