1use crate::axis::Axis;
4use std::{
5 ops::{Index, IndexMut, Not},
6 slice,
7};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11#[cfg_attr(
12 feature = "impl-serde",
13 derive(serde::Serialize, serde::Deserialize)
14)]
15pub enum Direction {
16 Up,
18 Down,
20 Left,
22 Right,
24}
25
26impl Direction {
27 pub const ALL: [Direction; 4] =
30 [Direction::Up, Direction::Down, Direction::Left, Direction::Right];
31
32 pub fn iter() -> Iter {
65 Iter { inner: Self::ALL.iter() }
66 }
67
68 pub fn from_axis_pos(axis: Axis) -> Self {
71 match axis {
72 Axis::X => Direction::Right,
73 Axis::Y => Direction::Down,
74 }
75 }
76
77 pub fn from_axis_neg(axis: Axis) -> Self {
80 match axis {
81 Axis::X => Direction::Left,
82 Axis::Y => Direction::Up,
83 }
84 }
85
86 pub fn axis(self) -> Axis {
88 match self {
89 Direction::Up | Direction::Down => Axis::Y,
90 Direction::Left | Direction::Right => Axis::X,
91 }
92 }
93
94 pub fn rotate_clockwise(self) -> Self {
96 match self {
97 Direction::Down => Direction::Left,
98 Direction::Left => Direction::Up,
99 Direction::Up => Direction::Right,
100 Direction::Right => Direction::Down,
101 }
102 }
103
104 pub fn rotate_countercw(self) -> Self {
106 match self {
107 Direction::Left => Direction::Down,
108 Direction::Down => Direction::Right,
109 Direction::Right => Direction::Up,
110 Direction::Up => Direction::Left,
111 }
112 }
113}
114
115impl Not for Direction {
116 type Output = Direction;
117
118 fn not(self) -> Self::Output {
119 match self {
120 Direction::Up => Direction::Down,
121 Direction::Down => Direction::Up,
122 Direction::Left => Direction::Right,
123 Direction::Right => Direction::Left,
124 }
125 }
126}
127
128#[derive(Debug, Clone)]
130pub struct Iter {
131 inner: slice::Iter<'static, Direction>,
132}
133
134impl Iterator for Iter {
135 type Item = Direction;
136
137 fn next(&mut self) -> Option<Self::Item> {
138 self.inner.next().copied()
139 }
140
141 fn size_hint(&self) -> (usize, Option<usize>) {
142 self.inner.size_hint()
143 }
144}
145
146impl DoubleEndedIterator for Iter {
147 fn next_back(&mut self) -> Option<Self::Item> {
148 self.inner.next_back().copied()
149 }
150}
151
152impl ExactSizeIterator for Iter {}
153
154#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
156#[cfg_attr(
157 feature = "impl-serde",
158 derive(serde::Serialize, serde::Deserialize)
159)]
160pub struct DirecVector<T> {
161 pub magnitude: T,
163 pub direction: Direction,
165}
166
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
169#[cfg_attr(
170 feature = "impl-serde",
171 derive(serde::Serialize, serde::Deserialize)
172)]
173pub struct DirecMap<T> {
174 pub up: T,
176 pub left: T,
178 pub down: T,
180 pub right: T,
182}
183
184impl<T> DirecMap<T> {
185 pub fn from_direcs<F>(mut map: F) -> Self
187 where
188 F: FnMut(Direction) -> T,
189 {
190 Self {
191 up: map(Direction::Up),
192 left: map(Direction::Left),
193 down: map(Direction::Down),
194 right: map(Direction::Right),
195 }
196 }
197}
198
199impl<T> Index<Direction> for DirecMap<T> {
200 type Output = T;
201
202 fn index(&self, index: Direction) -> &Self::Output {
203 match index {
204 Direction::Up => &self.up,
205 Direction::Left => &self.left,
206 Direction::Down => &self.down,
207 Direction::Right => &self.right,
208 }
209 }
210}
211
212impl<T> IndexMut<Direction> for DirecMap<T> {
213 fn index_mut(&mut self, index: Direction) -> &mut Self::Output {
214 match index {
215 Direction::Up => &mut self.up,
216 Direction::Left => &mut self.left,
217 Direction::Down => &mut self.down,
218 Direction::Right => &mut self.right,
219 }
220 }
221}