use std::sync::Arc;
use arrow_array::cast::AsArray;
use arrow_array::{Array, ArrayRef, ArrowPrimitiveType, PrimitiveArray};
use runlength::{RleLike, RleRef};
use crate::error::{Error, Result};
use crate::numeric::with_numeric_type;
use crate::rle::ArrowRle;
fn core_view<'a, T: ArrowPrimitiveType>(rle: &'a ArrowRle) -> Result<RleRef<'a, T::Native>> {
let values = rle.values.as_primitive::<T>();
if values.null_count() > 0 {
return Err(Error::UnexpectedNulls);
}
Ok(RleRef::from_ends(&rle.ends, values.values())?)
}
fn single<T: ArrowPrimitiveType>(value: Option<T::Native>) -> ArrayRef {
Arc::new(std::iter::once(value).collect::<PrimitiveArray<T>>())
}
impl ArrowRle {
pub fn sum(&self) -> Result<ArrayRef> {
with_numeric_type!(self.values, |T| Ok(single::<T>(Some(
core_view::<T>(self)?.sum()
))))
}
pub fn mean(&self) -> Result<Option<f64>> {
with_numeric_type!(self.values, |T| Ok(core_view::<T>(self)?.mean()))
}
pub fn variance(&self, ddof: i64) -> Result<Option<f64>> {
with_numeric_type!(self.values, |T| Ok(core_view::<T>(self)?.variance(ddof)))
}
pub fn std(&self, ddof: i64) -> Result<Option<f64>> {
Ok(self.variance(ddof)?.map(f64::sqrt))
}
pub fn min(&self) -> Result<ArrayRef> {
with_numeric_type!(self.values, |T| Ok(single::<T>(
core_view::<T>(self)?.min().copied()
)))
}
pub fn max(&self) -> Result<ArrayRef> {
with_numeric_type!(self.values, |T| Ok(single::<T>(
core_view::<T>(self)?.max().copied()
)))
}
}