use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum Axis {
X,
Y,
Z,
}
impl Axis {
pub const ALL: [Axis; 3] = [Axis::X, Axis::Y, Axis::Z];
pub const fn index(self) -> usize {
self as usize
}
pub const fn from_index(i: usize) -> Option<Axis> {
match i {
0 => Some(Axis::X),
1 => Some(Axis::Y),
2 => Some(Axis::Z),
_ => None,
}
}
pub const fn next(self) -> Axis {
match self {
Axis::X => Axis::Y,
Axis::Y => Axis::Z,
Axis::Z => Axis::X,
}
}
pub const fn prev(self) -> Axis {
match self {
Axis::X => Axis::Z,
Axis::Y => Axis::X,
Axis::Z => Axis::Y,
}
}
pub const fn others(self) -> (Axis, Axis) {
(self.next(), self.prev())
}
pub const fn name(self) -> &'static str {
match self {
Axis::X => "x",
Axis::Y => "y",
Axis::Z => "z",
}
}
}
impl fmt::Display for Axis {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.name())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn indices_round_trip() {
for (i, a) in Axis::ALL.into_iter().enumerate() {
assert_eq!(a.index(), i);
assert_eq!(Axis::from_index(i), Some(a));
}
assert_eq!(Axis::from_index(3), None);
}
#[test]
fn cyclic_order() {
assert_eq!(Axis::X.others(), (Axis::Y, Axis::Z));
assert_eq!(Axis::Y.others(), (Axis::Z, Axis::X));
assert_eq!(Axis::Z.others(), (Axis::X, Axis::Y));
for a in Axis::ALL {
assert_eq!(a.next().prev(), a);
assert_eq!(a.next().next().next(), a);
}
assert_eq!(Axis::Y.to_string(), "y");
}
}