blob: 6e8cf892237e00734064c69d8a8bbc0c606e8e46 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
use serde_json::{Number, Value};
use super::DataType;
/// Trait declaring any type that is serializable to JSON. This includes all primitive types (bool, i32, etc.).
pub trait JsonSerializable: 'static {
fn into_json_value(self) -> Option<Value>;
}
/// Trait expressing a Rust type that has the same in-memory representation
/// as Arrow. This includes `i16`, `f32`, but excludes `bool` (which in arrow is represented in bits).
/// In little endian machines, types that implement [`ArrowNativeType`] can be memcopied to arrow buffers
/// as is.
pub trait ArrowNativeType:
std::fmt::Debug
+ Send
+ Sync
+ Copy
+ PartialOrd
+ std::str::FromStr
+ Default
+ JsonSerializable
{
/// Convert native type from usize.
#[inline]
fn from_usize(_: usize) -> Option<Self> {
None
}
/// Convert native type to usize.
#[inline]
fn to_usize(&self) -> Option<usize> {
None
}
/// Convert native type to isize.
#[inline]
fn to_isize(&self) -> Option<isize> {
None
}
/// Convert native type from i32.
#[inline]
fn from_i32(_: i32) -> Option<Self> {
None
}
/// Convert native type from i64.
#[inline]
fn from_i64(_: i64) -> Option<Self> {
None
}
}
/// Trait bridging the dynamic-typed nature of Arrow (via [`DataType`]) with the
/// static-typed nature of rust types ([`ArrowNativeType`]) for all types that implement [`ArrowNativeType`].
pub trait ArrowPrimitiveType: 'static {
/// Corresponding Rust native type for the primitive type.
type Native: ArrowNativeType;
/// the corresponding Arrow data type of this primitive type.
const DATA_TYPE: DataType;
/// Returns the byte width of this primitive type.
fn get_byte_width() -> usize {
std::mem::size_of::<Self::Native>()
}
/// Returns a default value of this primitive type.
///
/// This is useful for aggregate array ops like `sum()`, `mean()`.
fn default_value() -> Self::Native {
Default::default()
}
}
impl JsonSerializable for bool {
fn into_json_value(self) -> Option<Value> {
Some(self.into())
}
}
impl JsonSerializable for i8 {
fn into_json_value(self) -> Option<Value> {
Some(self.into())
}
}
impl ArrowNativeType for i8 {
#[inline]
fn from_usize(v: usize) -> Option<Self> {
num::FromPrimitive::from_usize(v)
}
#[inline]
fn to_usize(&self) -> Option<usize> {
num::ToPrimitive::to_usize(self)
}
#[inline]
fn to_isize(&self) -> Option<isize> {
num::ToPrimitive::to_isize(self)
}
}
impl JsonSerializable for i16 {
fn into_json_value(self) -> Option<Value> {
Some(self.into())
}
}
impl ArrowNativeType for i16 {
#[inline]
fn from_usize(v: usize) -> Option<Self> {
num::FromPrimitive::from_usize(v)
}
#[inline]
fn to_usize(&self) -> Option<usize> {
num::ToPrimitive::to_usize(self)
}
#[inline]
fn to_isize(&self) -> Option<isize> {
num::ToPrimitive::to_isize(self)
}
}
impl JsonSerializable for i32 {
fn into_json_value(self) -> Option<Value> {
Some(self.into())
}
}
impl ArrowNativeType for i32 {
#[inline]
fn from_usize(v: usize) -> Option<Self> {
num::FromPrimitive::from_usize(v)
}
#[inline]
fn to_usize(&self) -> Option<usize> {
num::ToPrimitive::to_usize(self)
}
#[inline]
fn to_isize(&self) -> Option<isize> {
num::ToPrimitive::to_isize(self)
}
/// Convert native type from i32.
#[inline]
fn from_i32(val: i32) -> Option<Self> {
Some(val)
}
}
impl JsonSerializable for i64 {
fn into_json_value(self) -> Option<Value> {
Some(Value::Number(Number::from(self)))
}
}
impl ArrowNativeType for i64 {
#[inline]
fn from_usize(v: usize) -> Option<Self> {
num::FromPrimitive::from_usize(v)
}
#[inline]
fn to_usize(&self) -> Option<usize> {
num::ToPrimitive::to_usize(self)
}
#[inline]
fn to_isize(&self) -> Option<isize> {
num::ToPrimitive::to_isize(self)
}
/// Convert native type from i64.
#[inline]
fn from_i64(val: i64) -> Option<Self> {
Some(val)
}
}
impl JsonSerializable for u8 {
fn into_json_value(self) -> Option<Value> {
Some(self.into())
}
}
impl ArrowNativeType for u8 {
#[inline]
fn from_usize(v: usize) -> Option<Self> {
num::FromPrimitive::from_usize(v)
}
#[inline]
fn to_usize(&self) -> Option<usize> {
num::ToPrimitive::to_usize(self)
}
#[inline]
fn to_isize(&self) -> Option<isize> {
num::ToPrimitive::to_isize(self)
}
}
impl JsonSerializable for u16 {
fn into_json_value(self) -> Option<Value> {
Some(self.into())
}
}
impl ArrowNativeType for u16 {
#[inline]
fn from_usize(v: usize) -> Option<Self> {
num::FromPrimitive::from_usize(v)
}
#[inline]
fn to_usize(&self) -> Option<usize> {
num::ToPrimitive::to_usize(self)
}
#[inline]
fn to_isize(&self) -> Option<isize> {
num::ToPrimitive::to_isize(self)
}
}
impl JsonSerializable for u32 {
fn into_json_value(self) -> Option<Value> {
Some(self.into())
}
}
impl ArrowNativeType for u32 {
#[inline]
fn from_usize(v: usize) -> Option<Self> {
num::FromPrimitive::from_usize(v)
}
#[inline]
fn to_usize(&self) -> Option<usize> {
num::ToPrimitive::to_usize(self)
}
#[inline]
fn to_isize(&self) -> Option<isize> {
num::ToPrimitive::to_isize(self)
}
}
impl JsonSerializable for u64 {
fn into_json_value(self) -> Option<Value> {
Some(self.into())
}
}
impl ArrowNativeType for u64 {
#[inline]
fn from_usize(v: usize) -> Option<Self> {
num::FromPrimitive::from_usize(v)
}
#[inline]
fn to_usize(&self) -> Option<usize> {
num::ToPrimitive::to_usize(self)
}
#[inline]
fn to_isize(&self) -> Option<isize> {
num::ToPrimitive::to_isize(self)
}
}
impl JsonSerializable for f32 {
fn into_json_value(self) -> Option<Value> {
Number::from_f64(f64::round(self as f64 * 1000.0) / 1000.0).map(Value::Number)
}
}
impl JsonSerializable for f64 {
fn into_json_value(self) -> Option<Value> {
Number::from_f64(self).map(Value::Number)
}
}
impl ArrowNativeType for f32 {}
impl ArrowNativeType for f64 {}
/// Allows conversion from supported Arrow types to a byte slice.
pub trait ToByteSlice {
/// Converts this instance into a byte slice
fn to_byte_slice(&self) -> &[u8];
}
impl<T: ArrowNativeType> ToByteSlice for [T] {
#[inline]
fn to_byte_slice(&self) -> &[u8] {
let raw_ptr = self.as_ptr() as *const T as *const u8;
unsafe {
std::slice::from_raw_parts(raw_ptr, self.len() * std::mem::size_of::<T>())
}
}
}
impl<T: ArrowNativeType> ToByteSlice for T {
#[inline]
fn to_byte_slice(&self) -> &[u8] {
let raw_ptr = self as *const T as *const u8;
unsafe { std::slice::from_raw_parts(raw_ptr, std::mem::size_of::<T>()) }
}
}