1use std::fmt::{Display, Formatter};
2
3#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
5pub enum Dir {
6 North,
7 East,
8 South,
9 West,
10}
11
12impl Dir {
13 pub const ALL: [Dir; 4] = [Dir::North, Dir::East, Dir::South, Dir::West];
17}
18
19impl Dir {
20 pub const fn opposite(self) -> Self {
24 match self {
25 Dir::North => Dir::South,
26 Dir::East => Dir::West,
27 Dir::South => Dir::North,
28 Dir::West => Dir::East,
29 }
30 }
31
32 pub const fn left(self) -> Self {
34 match self {
35 Dir::North => Dir::West,
36 Dir::East => Dir::North,
37 Dir::South => Dir::East,
38 Dir::West => Dir::South,
39 }
40 }
41
42 pub const fn right(self) -> Self {
44 match self {
45 Dir::North => Dir::East,
46 Dir::East => Dir::South,
47 Dir::South => Dir::West,
48 Dir::West => Dir::North,
49 }
50 }
51}
52
53impl Display for Dir {
54 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
55 write!(f, "{:?}", self)
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use crate::Dir;
62
63 #[test]
64 fn opposite() {
65 for dir in Dir::ALL {
66 assert_ne!(dir.opposite(), dir);
67 assert_eq!(dir.opposite().opposite(), dir);
68 }
69 }
70
71 #[test]
72 fn left_right() {
73 for dir in Dir::ALL {
74 assert_ne!(dir.left(), dir);
75 assert_ne!(dir.right(), dir);
76 assert_eq!(dir.left().right(), dir);
77 assert_eq!(dir.right().left(), dir);
78 assert_eq!(dir.right().right().right().right(), dir);
79 assert_eq!(dir.left().left().left().left(), dir);
80 }
81 }
82}