use super::Error;
use ndarray::{ArrayView1, Ix1, ShapeBuilder, SliceInfo, SliceInfoElem};
use std::fmt::Debug;
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SortOrder {
Ascending,
Descending,
Unsorted,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Monotonicity {
pub order: SortOrder,
pub strict: bool,
}
impl Monotonicity {
pub fn is_ascending(&self) -> bool {
self.order == SortOrder::Ascending
}
pub fn is_descending(&self) -> bool {
self.order == SortOrder::Descending
}
pub fn is_monotonic(&self) -> bool {
self.is_ascending() || self.is_descending()
}
pub fn is_strictly_ascending(&self) -> bool {
self.is_ascending() && self.strict
}
pub fn is_strictly_descending(&self) -> bool {
self.is_descending() && self.strict
}
pub fn is_strictly_monotonic(&self) -> bool {
self.is_monotonic() && self.strict
}
}
pub(crate) fn slice_array<T: Clone + Debug>(
array: &[T],
slice_info: &SliceInfoElem,
) -> Result<Vec<T>, Error> {
if matches!(slice_info, SliceInfoElem::NewAxis) {
return Err("SliceInfoElem::NewAxis is not supported".into());
}
let strided_shape = Ix1(array.len()).strides(Ix1(1));
let view = unsafe { ArrayView1::from_shape_ptr(strided_shape, array.as_ptr()) };
let slice = slice_view1(view, slice_info)?;
Ok(slice.to_vec())
}
pub(crate) fn slice_view1<'a, T: Clone + Debug>(
view: ArrayView1<'a, T>,
slice_info: &SliceInfoElem,
) -> Result<ArrayView1<'a, T>, Error> {
let slice_info: &[SliceInfoElem] = &[*slice_info];
let slice_info: SliceInfo<&[SliceInfoElem], Ix1, Ix1> = SliceInfo::try_from(slice_info)
.map_err(|e| format!("Failed to convert &[SliceInfoElem] to SliceInfo: {e}"))?;
Ok(view.slice_move(slice_info))
}