1use crate::{i256, IntervalDayTime, IntervalMonthDayNano};
19use half::f16;
20
21mod private {
22 pub trait Sealed {}
23}
24
25pub trait ArrowNativeType:
51 std::fmt::Debug + Send + Sync + Copy + PartialOrd + Default + private::Sealed + 'static
52{
53 fn get_byte_width() -> usize {
55 std::mem::size_of::<Self>()
56 }
57
58 fn from_usize(_: usize) -> Option<Self>;
63
64 fn as_usize(self) -> usize;
68
69 fn usize_as(i: usize) -> Self;
73
74 fn to_usize(self) -> Option<usize>;
79
80 fn to_isize(self) -> Option<isize>;
85
86 fn to_i64(self) -> Option<i64>;
91}
92
93macro_rules! native_integer {
94 ($t: ty $(, $from:ident)*) => {
95 impl private::Sealed for $t {}
96 impl ArrowNativeType for $t {
97 #[inline]
98 fn from_usize(v: usize) -> Option<Self> {
99 v.try_into().ok()
100 }
101
102 #[inline]
103 fn to_usize(self) -> Option<usize> {
104 self.try_into().ok()
105 }
106
107 #[inline]
108 fn to_isize(self) -> Option<isize> {
109 self.try_into().ok()
110 }
111
112 #[inline]
113 fn to_i64(self) -> Option<i64> {
114 self.try_into().ok()
115 }
116
117 #[inline]
118 fn as_usize(self) -> usize {
119 self as _
120 }
121
122 #[inline]
123 fn usize_as(i: usize) -> Self {
124 i as _
125 }
126 }
127 };
128}
129
130native_integer!(i8);
131native_integer!(i16);
132native_integer!(i32);
133native_integer!(i64);
134native_integer!(i128);
135native_integer!(u8);
136native_integer!(u16);
137native_integer!(u32);
138native_integer!(u64);
139native_integer!(u128);
140
141macro_rules! native_float {
142 ($t:ty, $s:ident, $as_usize: expr, $i:ident, $usize_as: expr) => {
143 impl private::Sealed for $t {}
144 impl ArrowNativeType for $t {
145 #[inline]
146 fn from_usize(_: usize) -> Option<Self> {
147 None
148 }
149
150 #[inline]
151 fn to_usize(self) -> Option<usize> {
152 None
153 }
154
155 #[inline]
156 fn to_isize(self) -> Option<isize> {
157 None
158 }
159
160 #[inline]
161 fn to_i64(self) -> Option<i64> {
162 None
163 }
164
165 #[inline]
166 fn as_usize($s) -> usize {
167 $as_usize
168 }
169
170 #[inline]
171 fn usize_as($i: usize) -> Self {
172 $usize_as
173 }
174 }
175 };
176}
177
178native_float!(f16, self, self.to_f32() as _, i, f16::from_f32(i as _));
179native_float!(f32, self, self as _, i, i as _);
180native_float!(f64, self, self as _, i, i as _);
181
182impl private::Sealed for i256 {}
183impl ArrowNativeType for i256 {
184 fn from_usize(u: usize) -> Option<Self> {
185 Some(Self::from_parts(u as u128, 0))
186 }
187
188 fn as_usize(self) -> usize {
189 self.to_parts().0 as usize
190 }
191
192 fn usize_as(i: usize) -> Self {
193 Self::from_parts(i as u128, 0)
194 }
195
196 fn to_usize(self) -> Option<usize> {
197 let (low, high) = self.to_parts();
198 if high != 0 {
199 return None;
200 }
201 low.try_into().ok()
202 }
203
204 fn to_isize(self) -> Option<isize> {
205 self.to_i128()?.try_into().ok()
206 }
207
208 fn to_i64(self) -> Option<i64> {
209 self.to_i128()?.try_into().ok()
210 }
211}
212
213impl private::Sealed for IntervalMonthDayNano {}
214impl ArrowNativeType for IntervalMonthDayNano {
215 fn from_usize(_: usize) -> Option<Self> {
216 None
217 }
218
219 fn as_usize(self) -> usize {
220 ((self.months as u64) | ((self.days as u64) << 32)) as usize
221 }
222
223 fn usize_as(i: usize) -> Self {
224 Self::new(i as _, ((i as u64) >> 32) as _, 0)
225 }
226
227 fn to_usize(self) -> Option<usize> {
228 None
229 }
230
231 fn to_isize(self) -> Option<isize> {
232 None
233 }
234
235 fn to_i64(self) -> Option<i64> {
236 None
237 }
238}
239
240impl private::Sealed for IntervalDayTime {}
241impl ArrowNativeType for IntervalDayTime {
242 fn from_usize(_: usize) -> Option<Self> {
243 None
244 }
245
246 fn as_usize(self) -> usize {
247 ((self.days as u64) | ((self.milliseconds as u64) << 32)) as usize
248 }
249
250 fn usize_as(i: usize) -> Self {
251 Self::new(i as _, ((i as u64) >> 32) as _)
252 }
253
254 fn to_usize(self) -> Option<usize> {
255 None
256 }
257
258 fn to_isize(self) -> Option<isize> {
259 None
260 }
261
262 fn to_i64(self) -> Option<i64> {
263 None
264 }
265}
266
267pub trait ToByteSlice {
269 fn to_byte_slice(&self) -> &[u8];
271}
272
273impl<T: ArrowNativeType> ToByteSlice for [T] {
274 #[inline]
275 fn to_byte_slice(&self) -> &[u8] {
276 let raw_ptr = self.as_ptr() as *const u8;
277 unsafe { std::slice::from_raw_parts(raw_ptr, std::mem::size_of_val(self)) }
278 }
279}
280
281impl<T: ArrowNativeType> ToByteSlice for T {
282 #[inline]
283 fn to_byte_slice(&self) -> &[u8] {
284 let raw_ptr = self as *const T as *const u8;
285 unsafe { std::slice::from_raw_parts(raw_ptr, std::mem::size_of::<T>()) }
286 }
287}
288
289#[cfg(test)]
290mod tests {
291 use super::*;
292
293 #[test]
294 fn test_i256() {
295 let a = i256::from_parts(0, 0);
296 assert_eq!(a.as_usize(), 0);
297 assert_eq!(a.to_usize().unwrap(), 0);
298 assert_eq!(a.to_isize().unwrap(), 0);
299
300 let a = i256::from_parts(0, -1);
301 assert_eq!(a.as_usize(), 0);
302 assert!(a.to_usize().is_none());
303 assert!(a.to_usize().is_none());
304
305 let a = i256::from_parts(u128::MAX, -1);
306 assert_eq!(a.as_usize(), usize::MAX);
307 assert!(a.to_usize().is_none());
308 assert_eq!(a.to_isize().unwrap(), -1);
309 }
310
311 #[test]
312 fn test_interval_usize() {
313 assert_eq!(IntervalDayTime::new(1, 0).as_usize(), 1);
314 assert_eq!(IntervalMonthDayNano::new(1, 0, 0).as_usize(), 1);
315
316 let a = IntervalDayTime::new(23, 53);
317 let b = IntervalDayTime::usize_as(a.as_usize());
318 assert_eq!(a, b);
319
320 let a = IntervalMonthDayNano::new(23, 53, 0);
321 let b = IntervalMonthDayNano::usize_as(a.as_usize());
322 assert_eq!(a, b);
323 }
324}