use crate::{
Length, NonNullable, Nullability, Nullable,
buffer::{BufferType, VecBuffer},
logical::{LogicalArray, LogicalArrayType},
offset::{self, Offset},
};
use std::{collections::VecDeque, marker::PhantomData};
mod boolean;
pub use boolean::*;
mod fixed_size_binary;
pub use fixed_size_binary::*;
mod fixed_size_list;
pub use fixed_size_list::*;
mod fixed_size_primitive;
pub use fixed_size_primitive::*;
mod null;
pub use null::*;
mod string;
pub use string::*;
mod r#struct;
pub use r#struct::*;
pub mod union;
pub use union::*;
mod variable_size_binary;
pub use variable_size_binary::*;
mod variable_size_list;
pub use variable_size_list::*;
pub trait Array {
type Item;
}
pub trait ArrayType<T: ?Sized> {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType>: Array;
}
pub type ArrayTypeOf<T, Buffer = VecBuffer, OffsetItem = offset::NA, UnionLayout = union::NA> =
<T as ArrayType<T>>::Array<Buffer, OffsetItem, UnionLayout>;
pub type OptionArrayTypeOf<
T,
Buffer = VecBuffer,
OffsetItem = offset::NA,
UnionLayout = union::NA,
> = <Option<T> as ArrayType<T>>::Array<Buffer, OffsetItem, UnionLayout>;
pub type NullableArrayTypeOf<
Nullable,
T,
Buffer,
OffsetItem = offset::NA,
UnionLayout = union::NA,
> = <<Nullable as Nullability>::Item<T> as ArrayType<T>>::Array<Buffer, OffsetItem, UnionLayout>;
impl<T: ArrayType<U> + ?Sized, U> ArrayType<U> for &T {
type Array<Buffer: BufferType, OfsetItem: Offset, UnionLayout: UnionType> =
<T as ArrayType<U>>::Array<Buffer, OfsetItem, UnionLayout>;
}
pub trait Layout {
type Buffer: BufferType;
type Offset: Offset;
type Union: UnionType;
}
macro_rules! impl_array_type {
($ty:ty, $array:ty) => {
impl ArrayType<$ty> for $ty {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> = $array;
}
};
($ty:ty, $array:ty, $inner:ty) => {
impl ArrayType<$inner> for $ty {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> = $array;
}
};
}
impl_array_type!(bool, BooleanArray<NonNullable, Buffer>);
impl_array_type!(Option<bool>, BooleanArray<Nullable, Buffer>, bool);
impl_array_type!(u8, FixedSizePrimitiveArray<u8, NonNullable, Buffer>);
impl_array_type!(Option<u8>, FixedSizePrimitiveArray<u8, Nullable, Buffer>, u8);
impl_array_type!(i8, FixedSizePrimitiveArray<i8, NonNullable, Buffer>);
impl_array_type!(Option<i8>, FixedSizePrimitiveArray<i8, Nullable, Buffer>, i8);
impl_array_type!(u16, FixedSizePrimitiveArray<u16, NonNullable, Buffer>);
impl_array_type!(Option<u16>, FixedSizePrimitiveArray<u16, Nullable, Buffer>, u16);
impl_array_type!(i16, FixedSizePrimitiveArray<i16, NonNullable, Buffer>);
impl_array_type!(Option<i16>, FixedSizePrimitiveArray<i16, Nullable, Buffer>, i16);
impl_array_type!(u32, FixedSizePrimitiveArray<u32, NonNullable, Buffer>);
impl_array_type!(Option<u32>, FixedSizePrimitiveArray<u32, Nullable, Buffer>, u32);
impl_array_type!(i32, FixedSizePrimitiveArray<i32, NonNullable, Buffer>);
impl_array_type!(Option<i32>, FixedSizePrimitiveArray<i32, Nullable, Buffer>, i32);
impl_array_type!(u64, FixedSizePrimitiveArray<u64, NonNullable, Buffer>);
impl_array_type!(Option<u64>, FixedSizePrimitiveArray<u64, Nullable, Buffer>, u64);
impl_array_type!(i64, FixedSizePrimitiveArray<i64, NonNullable, Buffer>);
impl_array_type!(Option<i64>, FixedSizePrimitiveArray<i64, Nullable, Buffer>, i64);
#[cfg(not(feature = "arrow-rs"))]
impl_array_type!(u128, FixedSizePrimitiveArray<u128, NonNullable, Buffer>);
#[cfg(not(feature = "arrow-rs"))]
impl_array_type!(Option<u128>, FixedSizePrimitiveArray<u128, Nullable, Buffer>, u128);
impl_array_type!(i128, FixedSizePrimitiveArray<i128, NonNullable, Buffer>);
impl_array_type!(Option<i128>, FixedSizePrimitiveArray<i128, Nullable, Buffer>, i128);
#[cfg(not(feature = "arrow-rs"))]
impl_array_type!(usize, FixedSizePrimitiveArray<usize, NonNullable, Buffer>);
#[cfg(not(feature = "arrow-rs"))]
impl_array_type!(Option<usize>, FixedSizePrimitiveArray<usize, Nullable, Buffer>, usize);
#[cfg(not(feature = "arrow-rs"))]
impl_array_type!(isize, FixedSizePrimitiveArray<isize, NonNullable, Buffer>);
#[cfg(not(feature = "arrow-rs"))]
impl_array_type!(Option<isize>, FixedSizePrimitiveArray<isize, Nullable, Buffer>, isize);
impl_array_type!(f32, FixedSizePrimitiveArray<f32, NonNullable, Buffer>);
impl_array_type!(Option<f32>, FixedSizePrimitiveArray<f32, Nullable, Buffer>, f32);
impl_array_type!(f64, FixedSizePrimitiveArray<f64, NonNullable, Buffer>);
impl_array_type!(Option<f64>, FixedSizePrimitiveArray<f64, Nullable, Buffer>, f64);
impl_array_type!((), NullArray<(), NonNullable, Buffer>);
impl_array_type!(Option<()>, NullArray<(), Nullable, Buffer>, ());
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FixedSizeBinary<const N: usize>([u8; N]);
impl<const N: usize> Default for FixedSizeBinary<N> {
fn default() -> Self {
Self([u8::default(); N])
}
}
impl<const N: usize> ArrayType<FixedSizeBinary<N>> for FixedSizeBinary<N> {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
FixedSizeBinaryArray<N, NonNullable, Buffer>;
}
impl<const N: usize> ArrayType<FixedSizeBinary<N>> for Option<FixedSizeBinary<N>> {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
FixedSizeBinaryArray<N, Nullable, Buffer>;
}
impl<const N: usize> From<&[u8; N]> for FixedSizeBinary<N> {
fn from(value: &[u8; N]) -> Self {
Self(*value)
}
}
impl<const N: usize> From<[u8; N]> for FixedSizeBinary<N> {
fn from(value: [u8; N]) -> Self {
Self(value)
}
}
impl<const N: usize> From<FixedSizeBinary<N>> for [u8; N] {
fn from(value: FixedSizeBinary<N>) -> Self {
value.0
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct VariableSizeBinary(Vec<u8>);
impl ArrayType<VariableSizeBinary> for VariableSizeBinary {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
LogicalArray<Self, NonNullable, Buffer, OffsetItem, UnionLayout>;
}
impl ArrayType<VariableSizeBinary> for Option<VariableSizeBinary> {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
LogicalArray<VariableSizeBinary, Nullable, Buffer, OffsetItem, UnionLayout>;
}
#[cfg(feature = "arrow-rs")]
impl crate::arrow::LogicalArrayType<VariableSizeBinary> for VariableSizeBinary {
type ExtensionType = crate::arrow::NoExtensionType;
}
impl LogicalArrayType<VariableSizeBinary> for VariableSizeBinary {
type ArrayType = Vec<u8>;
fn from_array_type(item: Self::ArrayType) -> Self {
item.into()
}
fn into_array_type(self) -> Self::ArrayType {
self.into()
}
}
impl From<Vec<u8>> for VariableSizeBinary {
fn from(value: Vec<u8>) -> Self {
Self(value)
}
}
impl From<VariableSizeBinary> for Vec<u8> {
fn from(value: VariableSizeBinary) -> Self {
value.0
}
}
impl Length for VariableSizeBinary {
fn len(&self) -> usize {
self.0.len()
}
}
impl IntoIterator for VariableSizeBinary {
type Item = u8;
type IntoIter = std::vec::IntoIter<u8>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<T: ArrayType<T>, const N: usize> ArrayType<[T; N]> for [T; N] {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
FixedSizeListArray<N, ArrayTypeOf<T, Buffer, OffsetItem, UnionLayout>, NonNullable, Buffer>;
}
impl<T: ArrayType<T>, const N: usize> ArrayType<[T; N]> for Option<[T; N]> {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
FixedSizeListArray<N, ArrayTypeOf<T, Buffer, OffsetItem, UnionLayout>, Nullable, Buffer>;
}
impl<T, const N: usize> ArrayType<[Option<T>; N]> for [Option<T>; N]
where
Option<T>: ArrayType<T>,
{
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> = FixedSizeListArray<
N,
OptionArrayTypeOf<T, Buffer, OffsetItem, UnionLayout>,
NonNullable,
Buffer,
>;
}
impl<T, const N: usize> ArrayType<[Option<T>; N]> for Option<[Option<T>; N]>
where
Option<T>: ArrayType<T>,
{
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> = FixedSizeListArray<
N,
OptionArrayTypeOf<T, Buffer, OffsetItem, UnionLayout>,
Nullable,
Buffer,
>;
}
impl ArrayType<str> for str {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
StringArray<NonNullable, OffsetItem, Buffer>;
}
impl<'a> ArrayType<&'a str> for &'a str {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
StringArray<NonNullable, OffsetItem, Buffer>;
}
impl<'a> ArrayType<&'a str> for Option<&'a str> {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
StringArray<Nullable, OffsetItem, Buffer>;
}
impl ArrayType<String> for String {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
StringArray<NonNullable, OffsetItem, Buffer>;
}
impl ArrayType<String> for Option<String> {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
StringArray<Nullable, OffsetItem, Buffer>;
}
impl<'a, T: ArrayType<T>> ArrayType<&'a [T]> for &'a [T] {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
VariableSizeListArray<ArrayTypeOf<T, Buffer>, NonNullable, OffsetItem, Buffer>;
}
impl<'a, T: ArrayType<T>> ArrayType<&'a [T]> for Option<&'a [T]> {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
VariableSizeListArray<ArrayTypeOf<T, Buffer>, Nullable, OffsetItem, Buffer>;
}
impl<'a, T> ArrayType<&'a [Option<T>]> for &'a [Option<T>]
where
Option<T>: ArrayType<T>,
{
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
VariableSizeListArray<OptionArrayTypeOf<T, Buffer>, NonNullable, OffsetItem, Buffer>;
}
impl<'a, T> ArrayType<&'a [Option<T>]> for Option<&'a [Option<T>]>
where
Option<T>: ArrayType<T>,
{
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
VariableSizeListArray<OptionArrayTypeOf<T, Buffer>, Nullable, OffsetItem, Buffer>;
}
impl<T: ArrayType<T>> ArrayType<Vec<T>> for Vec<T> {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
VariableSizeListArray<ArrayTypeOf<T, Buffer>, NonNullable, OffsetItem, Buffer>;
}
impl<T: ArrayType<T>> ArrayType<Vec<T>> for Option<Vec<T>> {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
VariableSizeListArray<ArrayTypeOf<T, Buffer>, Nullable, OffsetItem, Buffer>;
}
impl<T> ArrayType<Vec<Option<T>>> for Vec<Option<T>>
where
Option<T>: ArrayType<T>,
{
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
VariableSizeListArray<OptionArrayTypeOf<T, Buffer>, NonNullable, OffsetItem, Buffer>;
}
impl<T> ArrayType<Vec<Option<T>>> for Option<Vec<Option<T>>>
where
Option<T>: ArrayType<T>,
{
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
VariableSizeListArray<OptionArrayTypeOf<T, Buffer>, Nullable, OffsetItem, Buffer>;
}
impl<T: ArrayType<T>> ArrayType<VecDeque<T>> for VecDeque<T> {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
VariableSizeListArray<ArrayTypeOf<T, Buffer>, NonNullable, OffsetItem, Buffer>;
}
impl<T: ArrayType<T>> ArrayType<VecDeque<T>> for Option<VecDeque<T>> {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
VariableSizeListArray<ArrayTypeOf<T, Buffer>, Nullable, OffsetItem, Buffer>;
}
impl<T> ArrayType<VecDeque<Option<T>>> for VecDeque<Option<T>>
where
Option<T>: ArrayType<T>,
{
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
VariableSizeListArray<OptionArrayTypeOf<T, Buffer>, NonNullable, OffsetItem, Buffer>;
}
impl<T> ArrayType<VecDeque<Option<T>>> for Option<VecDeque<Option<T>>>
where
Option<T>: ArrayType<T>,
{
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> =
VariableSizeListArray<OptionArrayTypeOf<T, Buffer>, Nullable, OffsetItem, Buffer>;
}
impl<T> ArrayType<PhantomData<T>> for PhantomData<T> {
type Array<Buffer: BufferType, OffsetItem: Offset, UnionLayout: UnionType> = NullArray;
}