Skip to main content

grid_map/dir/
square.rs

1use std::fmt::{Display, Formatter};
2
3/// A direction on a square grid.
4#[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    //! Constants
14
15    /// All directions. (clockwise from north)
16    pub const ALL: [Dir; 4] = [Dir::North, Dir::East, Dir::South, Dir::West];
17}
18
19impl Dir {
20    //! Properties
21
22    /// Gets the opposite direction.
23    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    /// Gets the direction to the left (counter-clockwise).
33    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    /// Gets the direction to the right (clockwise).
43    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}