1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
3pub struct Point<T: Copy> {
4 pub x: T,
5 pub y: T,
6}
7
8impl<T: Copy> Point<T> {
9 #[inline]
19 pub const fn new(x: T, y: T) -> Self {
20 Self { x, y }
21 }
22}
23
24mod operator_overload {
25 use super::*;
26
27 use std::ops::Add;
28 impl<T: Copy + Add<Output = T>> Add for Point<T> {
29 type Output = Point<T>;
30
31 #[inline]
32 fn add(self, rhs: Self) -> Self::Output {
33 Self {
34 x: self.x + rhs.x,
35 y: self.y + rhs.y,
36 }
37 }
38 }
39
40 use std::ops::Sub;
41 impl<T: Copy + Sub<Output = T>> Sub for Point<T> {
42 type Output = Point<T>;
43
44 #[inline]
45 fn sub(self, rhs: Self) -> Self::Output {
46 Self {
47 x: self.x - rhs.x,
48 y: self.y - rhs.y,
49 }
50 }
51 }
52
53 use std::ops::Mul;
54 impl<U: Copy, T: Copy + Mul<U, Output = T>> Mul<U> for Point<T> {
55 type Output = Point<T>;
56
57 #[inline]
58 fn mul(self, rhs: U) -> Self::Output {
59 Self {
60 x: self.x * rhs,
61 y: self.y * rhs,
62 }
63 }
64 }
65
66 use std::ops::Div;
67 impl<U: Copy, T: Copy + Div<U, Output = T>> Div<U> for Point<T> {
68 type Output = Point<T>;
69
70 #[inline]
71 fn div(self, rhs: U) -> Self::Output {
72 Self {
73 x: self.x / rhs,
74 y: self.y / rhs,
75 }
76 }
77 }
78
79 use std::ops::Neg;
80 impl<T: Copy + Neg<Output = T>> Neg for Point<T> {
81 type Output = Point<T>;
82
83 #[inline]
84 fn neg(self) -> Self::Output {
85 Self {
86 x: -self.x,
87 y: -self.y,
88 }
89 }
90 }
91
92 use std::ops::AddAssign;
93 impl<T: Copy + AddAssign> AddAssign for Point<T> {
94 #[inline]
95 fn add_assign(&mut self, rhs: Self) {
96 self.x += rhs.x;
97 self.y += rhs.y;
98 }
99 }
100
101 use std::ops::SubAssign;
102 impl<T: Copy + SubAssign> SubAssign for Point<T> {
103 #[inline]
104 fn sub_assign(&mut self, rhs: Self) {
105 self.x -= rhs.x;
106 self.y -= rhs.y;
107 }
108 }
109
110 use std::ops::MulAssign;
111 impl<U: Copy, T: Copy + MulAssign<U>> MulAssign<U> for Point<T> {
112 #[inline]
113 fn mul_assign(&mut self, rhs: U) {
114 self.x *= rhs;
115 self.y *= rhs;
116 }
117 }
118
119 use std::ops::DivAssign;
120 impl<U: Copy, T: Copy + DivAssign<U>> DivAssign<U> for Point<T> {
121 #[inline]
122 fn div_assign(&mut self, rhs: U) {
123 self.x /= rhs;
124 self.y /= rhs;
125 }
126 }
127
128 #[cfg(test)]
129 mod tests {
130 use super::*;
131
132 #[test]
133 fn point_add_test() {
134 let p1 = Point::new(1, 2);
135 let p2 = Point::new(3, 4);
136 let p3 = p1 + p2;
137 assert_eq!(p3, Point::new(4, 6));
138 }
139
140 #[test]
141 fn point_sub_test() {
142 let p1 = Point::new(1, 2);
143 let p2 = Point::new(3, 4);
144 let p3 = p1 - p2;
145 assert_eq!(p3, Point::new(-2, -2));
146 }
147
148 #[test]
149 fn point_mul_test() {
150 let p1 = Point::new(1, 2);
151 let p2 = p1 * 3;
152 assert_eq!(p2, Point::new(3, 6));
153 }
154
155 #[test]
156 fn point_div_test() {
157 let p1 = Point::new(1, 2);
158 let p2 = p1 / 2;
159 assert_eq!(p2, Point::new(0, 1));
160 }
161
162 #[test]
163 fn point_neg_test() {
164 let p1 = Point::new(1, 2);
165 let p2 = -p1;
166 assert_eq!(p2, Point::new(-1, -2));
167 }
168
169 #[test]
170 fn point_add_assign_test() {
171 let mut p1 = Point::new(1, 2);
172 let p2 = Point::new(3, 4);
173 p1 += p2;
174 assert_eq!(p1, Point::new(4, 6));
175 }
176
177 #[test]
178 fn point_sub_assign_test() {
179 let mut p1 = Point::new(1, 2);
180 let p2 = Point::new(3, 4);
181 p1 -= p2;
182 assert_eq!(p1, Point::new(-2, -2));
183 }
184
185 #[test]
186 fn point_mul_assign_test() {
187 let mut p1 = Point::new(1, 2);
188 p1 *= 3;
189 assert_eq!(p1, Point::new(3, 6));
190 }
191
192 #[test]
193 fn point_div_assign_test() {
194 let mut p1 = Point::new(1, 2);
195 p1 /= 2;
196 assert_eq!(p1, Point::new(0, 1));
197 }
198 }
199}
200
201impl<T: Copy> From<(T, T)> for Point<T> {
202 #[inline]
203 fn from((x, y): (T, T)) -> Self {
204 Self { x, y }
205 }
206}