ae_direction/
direction.rs1use std::fmt::Display;
2
3use rand::{distributions::Standard, prelude::Distribution};
4
5#[derive(PartialEq, Clone, Debug)]
6pub enum Cardinal {
7 North,
8 East,
9 South,
10 West,
11}
12
13impl Display for Cardinal {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 match self {
16 Cardinal::North => write!(f, "north"),
17 Cardinal::East => write!(f, "east"),
18 Cardinal::South => write!(f, "south"),
19 Cardinal::West => write!(f, "west"),
20 }
21 }
22}
23
24#[derive(PartialEq, Clone, Debug)]
25pub enum Ordinal {
26 Northeast,
27 Southeast,
28 Southwest,
29 Northwest,
30}
31
32impl Display for Ordinal {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 match self {
35 Ordinal::Northeast => write!(f, "northeast"),
36 Ordinal::Southeast => write!(f, "southeast"),
37 Ordinal::Southwest => write!(f, "southwest"),
38 Ordinal::Northwest => write!(f, "northwest"),
39 }
40 }
41}
42
43#[derive(PartialEq, Clone, Debug)]
45pub enum Direction {
46 Cardinal(Cardinal),
47 Ordinal(Ordinal),
48}
49
50impl Distribution<Cardinal> for Standard {
51 fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Cardinal {
52 match rng.gen_range(0..=3) {
53 0 => Cardinal::North,
54 1 => Cardinal::East,
55 2 => Cardinal::South,
56 3 => Cardinal::West,
57 _ => unreachable!(),
58 }
59 }
60}
61
62impl Direction {
63 pub fn reverse(&self) -> Direction {
65 match self {
66 Direction::Cardinal(cardinal) => match cardinal {
67 Cardinal::North => Direction::Cardinal(Cardinal::South),
68 Cardinal::East => Direction::Cardinal(Cardinal::West),
69 Cardinal::South => Direction::Cardinal(Cardinal::North),
70 Cardinal::West => Direction::Cardinal(Cardinal::East),
71 },
72 Direction::Ordinal(ordinal) => match ordinal {
73 Ordinal::Northeast => Direction::Ordinal(Ordinal::Southwest),
74 Ordinal::Southeast => Direction::Ordinal(Ordinal::Northwest),
75 Ordinal::Southwest => Direction::Ordinal(Ordinal::Northeast),
76 Ordinal::Northwest => Direction::Ordinal(Ordinal::Southeast),
77 },
78 }
79 }
80
81 pub fn clockwise(&self) -> Direction {
83 match self {
84 Direction::Cardinal(cardinal) => match cardinal {
85 Cardinal::North => Direction::Cardinal(Cardinal::East),
86 Cardinal::East => Direction::Cardinal(Cardinal::South),
87 Cardinal::South => Direction::Cardinal(Cardinal::West),
88 Cardinal::West => Direction::Cardinal(Cardinal::North),
89 },
90 Direction::Ordinal(ordinal) => match ordinal {
91 Ordinal::Northeast => Direction::Ordinal(Ordinal::Southeast),
92 Ordinal::Southeast => Direction::Ordinal(Ordinal::Southwest),
93 Ordinal::Southwest => Direction::Ordinal(Ordinal::Northwest),
94 Ordinal::Northwest => Direction::Ordinal(Ordinal::Northeast),
95 },
96 }
97 }
98}
99
100impl Display for Direction {
101 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102 match self {
103 Direction::Cardinal(cardinal) => write!(f, "{}", cardinal),
104 Direction::Ordinal(ordinal) => write!(f, "{}", ordinal),
105 }
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[test]
114 fn clockwise() {
115 let dir = Direction::Cardinal(Cardinal::North);
116 assert_eq!(dir.clockwise(), Direction::Cardinal(Cardinal::East));
117
118 let dir = Direction::Ordinal(Ordinal::Southwest);
119 assert_eq!(dir.clockwise(), Direction::Ordinal(Ordinal::Northwest));
120 }
121
122 #[test]
123 fn reverse() {
124 let dir = Direction::Cardinal(Cardinal::North);
125 assert_eq!(dir.reverse(), Direction::Cardinal(Cardinal::South));
126
127 let dir = Direction::Ordinal(Ordinal::Southwest);
128 assert_eq!(dir.reverse(), Direction::Ordinal(Ordinal::Northeast));
129 }
130}