ponsic_types/
point.rs

1/// 点结构体
2#[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    /// 创建一个新的点
10    ///
11    /// # Examples
12    ///
13    /// ```
14    /// use ponsic_types::Point;
15    ///
16    /// let p = Point::new(1, 2);
17    /// ```
18    #[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}