ponsic_types/
size.rs

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