1use crate::number::{Integer, Number, Signed, UnsignedInteger};
4use std::fmt::Debug;
5use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Not, Sub, SubAssign};
6
7macro_rules! vec_impl {
8 ($n:literal, $tuple:tt =>
9 $(#[$m:meta])* $v:vis struct $s:ident{$($i:tt => $f:ident),+}
10 ) => {
11 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
12 $(#[$m])* $v struct $s<T: Number> {
13 $(pub $f: T,)+
14 }
15
16 impl<T: Number> $s<T> {
17 pub const ORIGIN: Self = Self{$($f: T::ZERO),+};
18
19 #[inline]
20 #[must_use]
21 pub const fn new($($f: T),+) -> Self {
22 Self{$($f),+}
23 }
24
25 #[inline]
27 #[must_use]
28 pub const fn splat(v: T) -> Self {
29 Self{$($f: v),+}
30 }
31
32 #[inline]
34 #[must_use]
35 pub fn map<O: Number>(self, mut f: impl FnMut(T) -> O) -> $s<O> {
36 $s{$($f: f(self.$f)),+}
37 }
38
39 #[inline]
41 #[must_use]
42 pub fn cast<O: Number + From<T>>(self) -> $s<O> {
43 self.map(O::from)
44 }
45
46 #[inline]
48 #[must_use]
49 pub fn manhattan_distance(self) -> T::Unsigned
50 where
51 T: Integer
52 {
53 T::Unsigned::ZERO $(+ self.$f.unsigned_abs())+
54 }
55
56 #[inline]
58 #[must_use]
59 pub fn manhattan_distance_to(self, rhs: Self) -> T::Unsigned
60 where
61 T: Integer
62 {
63 T::Unsigned::ZERO $(+ self.$f.abs_diff(rhs.$f))+
64 }
65
66 #[inline]
68 #[must_use]
69 pub fn manhattan_distance_to_aabb(self, min: Self, max: Self) -> T::Unsigned
70 where
71 T: Integer
72 {
73 T::Unsigned::ZERO $(
74 + min.$f.saturating_sub_0(self.$f)
75 + self.$f.saturating_sub_0(max.$f)
76 )+
77 }
78
79 #[inline]
81 #[must_use]
82 pub fn squared_euclidean_distance_to(self, rhs: Self) -> T {
83 T::ZERO $(+ self.$f.squared_diff(rhs.$f))+
84 }
85
86 #[inline]
90 #[must_use]
91 pub fn wrapping_add_signed(self, rhs: $s<T::Signed>) -> Self
92 where
93 T: UnsignedInteger,
94 {
95 Self{
96 $($f: self.$f.wrapping_add_signed(rhs.$f),)+
97 }
98 }
99
100 #[inline]
102 #[must_use]
103 pub fn component_min(self, rhs: Self) -> Self
104 where
105 T: Ord,
106 {
107 Self{
108 $($f: self.$f.min(rhs.$f),)+
109 }
110 }
111
112
113 #[inline]
115 #[must_use]
116 pub fn component_max(self, rhs: Self) -> Self
117 where
118 T: Ord,
119 {
120 Self{
121 $($f: self.$f.max(rhs.$f),)+
122 }
123 }
124 }
125
126 impl<T: Number> Add for $s<T> {
127 type Output = Self;
128
129 #[inline]
130 fn add(self, rhs: Self) -> Self {
131 Self{
132 $($f: self.$f + rhs.$f,)+
133 }
134 }
135 }
136
137 impl<T: Number> AddAssign for $s<T> {
138 #[inline]
139 fn add_assign(&mut self, rhs: Self) {
140 $(self.$f += rhs.$f;)+
141 }
142 }
143
144 impl<T: Number> Div<T> for $s<T> {
145 type Output = Self;
146
147 #[inline]
148 fn div(self, rhs: T) -> Self {
149 Self{
150 $($f: self.$f / rhs,)+
151 }
152 }
153 }
154
155 impl<T: Number> DivAssign<T> for $s<T> {
156 #[inline]
157 fn div_assign(&mut self, rhs: T) {
158 $(self.$f /= rhs;)+
159 }
160 }
161
162 impl<T: Number> Mul<T> for $s<T> {
163 type Output = Self;
164
165 #[inline]
166 fn mul(self, rhs: T) -> Self {
167 Self{
168 $($f: self.$f * rhs,)+
169 }
170 }
171 }
172
173 impl<T: Number> MulAssign<T> for $s<T> {
174 #[inline]
175 fn mul_assign(&mut self, rhs: T) {
176 $(self.$f *= rhs;)+
177 }
178 }
179
180 impl<T: Number> Sub for $s<T> {
181 type Output = Self;
182
183 #[inline]
184 fn sub(self, rhs: Self) -> Self {
185 Self{
186 $($f: self.$f - rhs.$f,)+
187 }
188 }
189 }
190
191 impl<T: Number> SubAssign for $s<T> {
192 #[inline]
193 fn sub_assign(&mut self, rhs: Self) {
194 $(self.$f -= rhs.$f;)+
195 }
196 }
197
198 impl<T: Number> From<[T; $n]> for $s<T> {
199 #[inline]
200 fn from(arr: [T; $n]) -> Self {
201 Self{$(
202 $f: arr[$i],
203 )+}
204 }
205 }
206
207 impl<T: Number> From<$tuple> for $s<T> {
208 #[inline]
209 fn from(arr: $tuple) -> Self {
210 Self{$(
211 $f: arr.$i,
212 )+}
213 }
214 }
215
216 impl<T: Number> From<$s<T>> for [T; $n] {
217 #[inline]
218 fn from(value: $s<T>) -> Self {
219 [$(value.$f),+]
220 }
221 }
222
223 impl<T: Number> From<$s<T>> for $tuple {
224 #[inline]
225 fn from(value: $s<T>) -> Self {
226 ($(value.$f),+)
227 }
228 }
229
230 vec_impl!(@widen $s{$($f),+},
231 u8 => [u16, u32, u64, u128, i16, i32, i64, i128, f32, f64],
232 u16 => [u32, u64, u128, i32, i64, i128, f32, f64],
233 u32 => [u64, u128, i64, i128, f64],
234 u64 => [u128, i128],
235 i8 => [i16, i32, i64, i128, f32, f64],
236 i16 => [i32, i64, i128, f32, f64],
237 i32 => [i64, i128, f64],
238 i64 => [i128],
239 );
240 };
241 (@widen $s:ident{$($f:ident),+}, $($from:ident => [$($to:ident),+],)+) => {$($(
242 impl From<$s<$from>> for $s<$to> {
243 #[inline(always)]
244 fn from(value: $s<$from>) -> Self {
245 value.cast()
246 }
247 }
248 )+)+};
249}
250
251vec_impl! {2, (T, T) =>
252 #[doc(alias("Vector", "Vector2", "Point", "Point2", "Point2D"))]
254 pub struct Vec2{0 => x, 1 => y}
255}
256
257impl<T: Signed> Vec2<T> {
258 pub const UP: Self = Self {
259 x: T::ZERO,
260 y: T::ONE,
261 };
262 pub const RIGHT: Self = Self {
263 x: T::ONE,
264 y: T::ZERO,
265 };
266 pub const DOWN: Self = Self {
267 x: T::ZERO,
268 y: T::MINUS_ONE,
269 };
270 pub const LEFT: Self = Self {
271 x: T::MINUS_ONE,
272 y: T::ZERO,
273 };
274 pub const DIRECTIONS: [Self; 4] = [Self::UP, Self::RIGHT, Self::DOWN, Self::LEFT];
275
276 #[inline]
278 #[must_use]
279 pub fn turn_right(self) -> Self {
280 Self {
281 x: self.y,
282 y: -self.x,
283 }
284 }
285
286 #[inline]
288 #[must_use]
289 pub fn turn_left(self) -> Self {
290 Self {
291 x: -self.y,
292 y: self.x,
293 }
294 }
295}
296
297vec_impl! {3, (T, T, T) =>
298 #[doc(alias("Vector3", "Point3", "Point3D"))]
300 pub struct Vec3{0 => x, 1 => y, 2 => z}
301}
302
303vec_impl! {4, (T, T, T, T) =>
304 #[doc(alias("Vector4", "Point4", "Point4D"))]
306 pub struct Vec4{0 => x, 1 => y, 2 => z, 3 => w}
307}
308
309#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
311#[repr(u8)]
312pub enum Direction {
313 #[default]
314 Up = 0,
315 Right,
316 Down,
317 Left,
318}
319
320impl Direction {
321 #[inline]
323 #[must_use]
324 pub fn turn(self, turn: Turn) -> Self {
325 Self::from((self as u8).wrapping_add_signed(turn as i8))
326 }
327
328 #[inline]
330 #[must_use]
331 pub fn turn_left(self) -> Self {
332 self.turn(Turn::Left)
333 }
334
335 #[inline]
337 #[must_use]
338 pub fn turn_right(self) -> Self {
339 self.turn(Turn::Right)
340 }
341}
342
343impl From<u8> for Direction {
344 #[inline]
345 fn from(value: u8) -> Self {
346 match value % 4 {
347 0 => Direction::Up,
348 1 => Direction::Right,
349 2 => Direction::Down,
350 3 => Direction::Left,
351 _ => unreachable!(),
352 }
353 }
354}
355
356impl Not for Direction {
357 type Output = Self;
358
359 #[inline]
360 fn not(self) -> Self::Output {
361 Self::from((self as u8).wrapping_add(2))
362 }
363}
364
365impl<T: Signed> From<Direction> for Vec2<T> {
366 #[inline]
367 fn from(value: Direction) -> Self {
368 Vec2::DIRECTIONS[value as usize]
369 }
370}
371
372impl<T: Signed> Add<Direction> for Vec2<T> {
373 type Output = Self;
374
375 #[inline]
376 fn add(self, rhs: Direction) -> Self::Output {
377 self + Vec2::from(rhs)
378 }
379}
380
381impl<T: Signed> Sub<Direction> for Vec2<T> {
382 type Output = Self;
383
384 #[inline]
385 fn sub(self, rhs: Direction) -> Self::Output {
386 self - Vec2::from(rhs)
387 }
388}
389
390#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
392#[repr(i8)]
393pub enum Turn {
394 #[doc(alias("Anticlockwise"))]
395 Left = -1,
396 #[doc(alias("Straight"))]
397 #[default]
398 None = 0,
399 #[doc(alias("Clockwise"))]
400 Right = 1,
401}