use arrow_buffer::BooleanBufferBuilder;
use vortex_buffer::{Buffer, BufferMut};
use vortex_dtype::NativePType;
use vortex_error::vortex_panic;
use crate::arrays::PrimitiveArray;
use crate::validity::Validity;
use crate::vtable::ValidityHelper;
use crate::{ArrayRef, IntoArray};
impl PrimitiveArray {
pub fn from_option_iter<T: NativePType, I: IntoIterator<Item = Option<T>>>(iter: I) -> Self {
let iter = iter.into_iter();
let mut values = BufferMut::with_capacity(iter.size_hint().0);
let mut validity = BooleanBufferBuilder::new(values.capacity());
for i in iter {
match i {
None => {
validity.append(false);
values.push(T::default());
}
Some(e) => {
validity.append(true);
values.push(e);
}
}
}
Self::new(values.freeze(), Validity::from(validity.finish()))
}
pub fn buffer<T: NativePType>(&self) -> Buffer<T> {
if T::PTYPE != self.ptype() {
vortex_panic!(
"Attempted to get buffer of type {} from array of type {}",
T::PTYPE,
self.ptype()
)
}
Buffer::from_byte_buffer(self.byte_buffer().clone())
}
pub fn into_buffer<T: NativePType>(self) -> Buffer<T> {
if T::PTYPE != self.ptype() {
vortex_panic!(
"Attempted to get buffer of type {} from array of type {}",
T::PTYPE,
self.ptype()
)
}
Buffer::from_byte_buffer(self.buffer)
}
pub fn into_buffer_mut<T: NativePType>(self) -> BufferMut<T> {
if T::PTYPE != self.ptype() {
vortex_panic!(
"Attempted to get buffer_mut of type {} from array of type {}",
T::PTYPE,
self.ptype()
)
}
self.into_buffer()
.try_into_mut()
.unwrap_or_else(|buffer| BufferMut::<T>::copy_from(&buffer))
}
#[allow(clippy::panic_in_result_fn)]
pub fn try_into_buffer_mut<T: NativePType>(self) -> Result<BufferMut<T>, PrimitiveArray> {
if T::PTYPE != self.ptype() {
vortex_panic!(
"Attempted to get buffer_mut of type {} from array of type {}",
T::PTYPE,
self.ptype()
)
}
let validity = self.validity().clone();
Buffer::<T>::from_byte_buffer(self.into_byte_buffer())
.try_into_mut()
.map_err(|buffer| PrimitiveArray::new(buffer, validity))
}
}
impl<T: NativePType> FromIterator<T> for PrimitiveArray {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let values = BufferMut::from_iter(iter);
PrimitiveArray::new(values, Validity::NonNullable)
}
}
impl<T: NativePType> IntoArray for Buffer<T> {
fn into_array(self) -> ArrayRef {
PrimitiveArray::new(self, Validity::NonNullable).into_array()
}
}
impl<T: NativePType> IntoArray for BufferMut<T> {
fn into_array(self) -> ArrayRef {
self.freeze().into_array()
}
}