1#[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 #[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}