use either::Either;
use super::utils::check_same_len;
use crate::array::PrimitiveArray;
use crate::types::NativeType;
#[inline]
pub fn unary<I, F>(array: &mut PrimitiveArray<I>, op: F)
where
I: NativeType,
F: Fn(I) -> I,
{
if let Some(values) = array.get_mut_values() {
values.iter_mut().for_each(|l| *l = op(*l));
} else {
let values = array.values().iter().map(|l| op(*l)).collect::<Vec<_>>();
array.set_values(values.into());
}
}
#[inline]
pub fn binary<T, D, F>(lhs: &mut PrimitiveArray<T>, rhs: &PrimitiveArray<D>, op: F)
where
T: NativeType,
D: NativeType,
F: Fn(T, D) -> T,
{
check_same_len(lhs, rhs).unwrap();
if let Some(rhs) = rhs.validity() {
if lhs.validity().is_none() {
lhs.set_validity(Some(rhs.clone()));
} else {
lhs.apply_validity(|bitmap| {
match bitmap.into_mut() {
Either::Left(immutable) => {
&immutable & rhs
},
Either::Right(mutable) => {
(mutable & rhs).into()
},
}
});
}
};
if let Some(values) = lhs.get_mut_values() {
values
.iter_mut()
.zip(rhs.values().iter())
.for_each(|(l, r)| *l = op(*l, *r));
} else {
let values = lhs
.values()
.iter()
.zip(rhs.values().iter())
.map(|(l, r)| op(*l, *r))
.collect::<Vec<_>>();
lhs.set_values(values.into());
}
}