1pub trait DirectionConvertible {
2 fn get_2xmod(self) -> Self;
3 fn get_2ymod(self) -> Self;
4 fn get_new_coord(self, axis: bool, screen: Self, window: Self) -> Self;
5 fn get_new_x_coord(self, screen: Self, window: Self) -> Self;
6 fn get_new_y_coord(self, screen: Self, window: Self) -> Self;
7}
8
9macro_rules! generate_mod_functions {
10 ($T: ty) => {
11 impl DirectionConvertible for $T {
12 fn get_2xmod(self) -> Self {
13 (self.clamp(1, 9) - 1) % 3
14 }
15
16 fn get_2ymod(self) -> Self {
17 2 - (self.clamp(1, 9) - 1) / 3
18 }
19
20 fn get_new_coord(
21 self,
22 axis: bool,
23 screen_distance: Self,
24 window_distance: Self,
25 ) -> Self {
26 let double_modifier;
27 if (axis) {
28 double_modifier = self.get_2ymod();
29 } else {
30 double_modifier = self.get_2xmod();
31 }
32
33 let screen_distance = screen_distance.clamp(0, <$T>::MAX / 2);
34 let window_distance = window_distance.clamp(0, screen_distance);
35
36 ((screen_distance - window_distance) * double_modifier) / 2
39 }
40
41 fn get_new_x_coord(self, screen_distance: Self, window_distance: Self) -> Self {
42 self.get_new_coord(false, screen_distance, window_distance)
43 }
44
45 fn get_new_y_coord(self, screen_distance: Self, window_distance: Self) -> Self {
46 self.get_new_coord(true, screen_distance, window_distance)
47 }
48 }
49 };
50}
51
52generate_mod_functions!(u16);
53generate_mod_functions!(u32);
54generate_mod_functions!(i16);
55generate_mod_functions!(i32);
56
57#[test]
58fn test_get_xmod() {
59 for n in [1, 4, 7] {
60 assert_eq!(n.get_2xmod(), 0);
61 }
62
63 for n in [2, 5, 8] {
64 assert_eq!(n.get_2xmod(), 1);
65 }
66
67 for n in [3, 6, 9] {
68 assert_eq!(n.get_2xmod(), 2);
69 }
70}
71
72#[test]
73fn test_get_ymod() {
74 for n in [7, 8, 9] {
75 assert_eq!(n.get_2ymod(), 0);
76 }
77
78 for n in [4, 5, 6] {
79 assert_eq!(n.get_2ymod(), 1);
80 }
81
82 for n in [1, 2, 3] {
83 assert_eq!(n.get_2ymod(), 2);
84 }
85}
86
87#[test]
88fn test_get_new_coord() {
89 for n in [1, 4, 7] as [u16; 3] {
90 println!("test new_x_coord block1 {:?}", n);
91 assert_eq!(n.get_new_x_coord(3840, 400), 0);
92 assert_eq!(n.get_new_x_coord(u16::MAX, u16::MAX), 0);
93 assert_eq!(n.get_new_x_coord(u16::MAX, 0), 0);
94 }
95
96 for n in [2, 5, 8] as [u16; 3] {
97 println!("test new_x_coord block2 {:?}", n);
98 assert_eq!(n.get_new_x_coord(3840, 400), 1720);
99 assert_eq!(n.get_new_x_coord(u16::MAX, u16::MAX), 0);
101 assert_eq!(n.get_new_x_coord(u16::MAX, 0), u16::MAX / 4);
103 }
104
105 for n in [3, 6, 9] as [u16; 3] {
106 println!("test new_x_coord block3 {:?}", n);
107 assert_eq!(n.get_new_x_coord(3840, 400), 3440);
108 assert_eq!(n.get_new_x_coord(u16::MAX, u16::MAX), 0);
109 assert_eq!(n.get_new_x_coord(u16::MAX, 0), u16::MAX / 2);
110 }
111
112 for n in [7, 8, 9] as [u16; 3] {
113 println!("test new_y_coord block1 {:?}", n);
114 assert_eq!(n.get_new_y_coord(3840, 400), 0);
115 assert_eq!(n.get_new_y_coord(u16::MAX, u16::MAX), 0);
116 assert_eq!(n.get_new_y_coord(u16::MAX, 0), 0);
117 }
118
119 for n in [4, 5, 6] as [u16; 3] {
120 println!("test new_y_coord block2 {:?}", n);
121 assert_eq!(n.get_new_y_coord(3840, 400), 1720);
122 assert_eq!(n.get_new_y_coord(u16::MAX, u16::MAX), 0);
123 assert_eq!(n.get_new_y_coord(u16::MAX, 0), u16::MAX / 4);
124 }
125
126 for n in [1, 2, 3] as [u16; 3] {
127 println!("test new_y_coord block3 {:?}", n);
128 assert_eq!(n.get_new_y_coord(3840, 400), 3440);
129 assert_eq!(n.get_new_y_coord(u16::MAX, u16::MAX), 0);
130 assert_eq!(n.get_new_y_coord(u16::MAX, 0), u16::MAX / 2);
131 }
132}