use thiserror::Error;
#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum AxisError {
#[error("axis {axis} is out of bounds for rank {rank}")]
OutOfBounds { axis: isize, rank: usize },
#[error("duplicate axis {axis}")]
Duplicate { axis: usize },
}
pub fn normalize_axis(axis: isize, rank: usize) -> Result<usize, AxisError> {
let rank_i = rank as isize;
let normalized = if axis < 0 { rank_i + axis } else { axis };
if normalized < 0 || normalized >= rank_i {
return Err(AxisError::OutOfBounds { axis, rank });
}
Ok(normalized as usize)
}
pub fn normalize_axes(axes: &[isize], rank: usize) -> Result<Vec<usize>, AxisError> {
let mut out = Vec::with_capacity(axes.len());
let mut seen = vec![false; rank];
for &axis in axes {
let normalized = normalize_axis(axis, rank)?;
if seen[normalized] {
return Err(AxisError::Duplicate { axis: normalized });
}
seen[normalized] = true;
out.push(normalized);
}
Ok(out)
}