1use thiserror::Error;
2
3#[derive(Debug, Clone, PartialEq, Eq, Error)]
5pub enum AxisError {
6 #[error("axis {axis} is out of bounds for rank {rank}")]
8 OutOfBounds { axis: isize, rank: usize },
9 #[error("duplicate axis {axis}")]
11 Duplicate { axis: usize },
12}
13
14pub fn normalize_axis(axis: isize, rank: usize) -> Result<usize, AxisError> {
25 let rank_i = rank as isize;
26 let normalized = if axis < 0 { rank_i + axis } else { axis };
27 if normalized < 0 || normalized >= rank_i {
28 return Err(AxisError::OutOfBounds { axis, rank });
29 }
30 Ok(normalized as usize)
31}
32
33pub fn normalize_axes(axes: &[isize], rank: usize) -> Result<Vec<usize>, AxisError> {
44 let mut out = Vec::with_capacity(axes.len());
45 let mut seen = vec![false; rank];
46 for &axis in axes {
47 let normalized = normalize_axis(axis, rank)?;
48 if seen[normalized] {
49 return Err(AxisError::Duplicate { axis: normalized });
50 }
51 seen[normalized] = true;
52 out.push(normalized);
53 }
54 Ok(out)
55}