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 #[deprecated(note = "please use `Option::Some` instead")]
96 fn from_i32(_: i32) -> Option<Self> {
97 None
98 }
99
100 #[deprecated(note = "please use `Option::Some` instead")]
104 fn from_i64(_: i64) -> Option<Self> {
105 None
106 }
107
108 #[deprecated(note = "please use `Option::Some` instead")]
112 fn from_i128(_: i128) -> Option<Self> {
113 None
114 }
115}
116
117macro_rules! native_integer {
118 ($t: ty $(, $from:ident)*) => {
119 impl private::Sealed for $t {}
120 impl ArrowNativeType for $t {
121 #[inline]
122 fn from_usize(v: usize) -> Option<Self> {
123 v.try_into().ok()
124 }
125
126 #[inline]
127 fn to_usize(self) -> Option<usize> {
128 self.try_into().ok()
129 }
130
131 #[inline]
132 fn to_isize(self) -> Option<isize> {
133 self.try_into().ok()
134 }
135
136 #[inline]
137 fn to_i64(self) -> Option<i64> {
138 self.try_into().ok()
139 }
140
141 #[inline]
142 fn as_usize(self) -> usize {
143 self as _
144 }
145
146 #[inline]
147 fn usize_as(i: usize) -> Self {
148 i as _
149 }
150
151
152 $(
153 #[inline]
154 fn $from(v: $t) -> Option<Self> {
155 Some(v)
156 }
157 )*
158 }
159 };
160}
161
162native_integer!(i8);
163native_integer!(i16);
164native_integer!(i32, from_i32);
165native_integer!(i64, from_i64);
166native_integer!(i128, from_i128);
167native_integer!(u8);
168native_integer!(u16);
169native_integer!(u32);
170native_integer!(u64);
171native_integer!(u128);
172
173macro_rules! native_float {
174 ($t:ty, $s:ident, $as_usize: expr, $i:ident, $usize_as: expr) => {
175 impl private::Sealed for $t {}
176 impl ArrowNativeType for $t {
177 #[inline]
178 fn from_usize(_: usize) -> Option<Self> {
179 None
180 }
181
182 #[inline]
183 fn to_usize(self) -> Option<usize> {
184 None
185 }
186
187 #[inline]
188 fn to_isize(self) -> Option<isize> {
189 None
190 }
191
192 #[inline]
193 fn to_i64(self) -> Option<i64> {
194 None
195 }
196
197 #[inline]
198 fn as_usize($s) -> usize {
199 $as_usize
200 }
201
202 #[inline]
203 fn usize_as($i: usize) -> Self {
204 $usize_as
205 }
206 }
207 };
208}
209
210native_float!(f16, self, self.to_f32() as _, i, f16::from_f32(i as _));
211native_float!(f32, self, self as _, i, i as _);
212native_float!(f64, self, self as _, i, i as _);
213
214impl private::Sealed for i256 {}
215impl ArrowNativeType for i256 {
216 fn from_usize(u: usize) -> Option<Self> {
217 Some(Self::from_parts(u as u128, 0))
218 }
219
220 fn as_usize(self) -> usize {
221 self.to_parts().0 as usize
222 }
223
224 fn usize_as(i: usize) -> Self {
225 Self::from_parts(i as u128, 0)
226 }
227
228 fn to_usize(self) -> Option<usize> {
229 let (low, high) = self.to_parts();
230 if high != 0 {
231 return None;
232 }
233 low.try_into().ok()
234 }
235
236 fn to_isize(self) -> Option<isize> {
237 self.to_i128()?.try_into().ok()
238 }
239
240 fn to_i64(self) -> Option<i64> {
241 self.to_i128()?.try_into().ok()
242 }
243}
244
245impl private::Sealed for IntervalMonthDayNano {}
246impl ArrowNativeType for IntervalMonthDayNano {
247 fn from_usize(_: usize) -> Option<Self> {
248 None
249 }
250
251 fn as_usize(self) -> usize {
252 ((self.months as u64) | ((self.days as u64) << 32)) as usize
253 }
254
255 fn usize_as(i: usize) -> Self {
256 Self::new(i as _, ((i as u64) >> 32) as _, 0)
257 }
258
259 fn to_usize(self) -> Option<usize> {
260 None
261 }
262
263 fn to_isize(self) -> Option<isize> {
264 None
265 }
266
267 fn to_i64(self) -> Option<i64> {
268 None
269 }
270}
271
272impl private::Sealed for IntervalDayTime {}
273impl ArrowNativeType for IntervalDayTime {
274 fn from_usize(_: usize) -> Option<Self> {
275 None
276 }
277
278 fn as_usize(self) -> usize {
279 ((self.days as u64) | ((self.milliseconds as u64) << 32)) as usize
280 }
281
282 fn usize_as(i: usize) -> Self {
283 Self::new(i as _, ((i as u64) >> 32) as _)
284 }
285
286 fn to_usize(self) -> Option<usize> {
287 None
288 }
289
290 fn to_isize(self) -> Option<isize> {
291 None
292 }
293
294 fn to_i64(self) -> Option<i64> {
295 None
296 }
297}
298
299pub trait ToByteSlice {
301 fn to_byte_slice(&self) -> &[u8];
303}
304
305impl<T: ArrowNativeType> ToByteSlice for [T] {
306 #[inline]
307 fn to_byte_slice(&self) -> &[u8] {
308 let raw_ptr = self.as_ptr() as *const u8;
309 unsafe { std::slice::from_raw_parts(raw_ptr, std::mem::size_of_val(self)) }
310 }
311}
312
313impl<T: ArrowNativeType> ToByteSlice for T {
314 #[inline]
315 fn to_byte_slice(&self) -> &[u8] {
316 let raw_ptr = self as *const T as *const u8;
317 unsafe { std::slice::from_raw_parts(raw_ptr, std::mem::size_of::<T>()) }
318 }
319}
320
321#[cfg(test)]
322mod tests {
323 use super::*;
324
325 #[test]
326 fn test_i256() {
327 let a = i256::from_parts(0, 0);
328 assert_eq!(a.as_usize(), 0);
329 assert_eq!(a.to_usize().unwrap(), 0);
330 assert_eq!(a.to_isize().unwrap(), 0);
331
332 let a = i256::from_parts(0, -1);
333 assert_eq!(a.as_usize(), 0);
334 assert!(a.to_usize().is_none());
335 assert!(a.to_usize().is_none());
336
337 let a = i256::from_parts(u128::MAX, -1);
338 assert_eq!(a.as_usize(), usize::MAX);
339 assert!(a.to_usize().is_none());
340 assert_eq!(a.to_isize().unwrap(), -1);
341 }
342
343 #[test]
344 fn test_interval_usize() {
345 assert_eq!(IntervalDayTime::new(1, 0).as_usize(), 1);
346 assert_eq!(IntervalMonthDayNano::new(1, 0, 0).as_usize(), 1);
347
348 let a = IntervalDayTime::new(23, 53);
349 let b = IntervalDayTime::usize_as(a.as_usize());
350 assert_eq!(a, b);
351
352 let a = IntervalMonthDayNano::new(23, 53, 0);
353 let b = IntervalMonthDayNano::usize_as(a.as_usize());
354 assert_eq!(a, b);
355 }
356}