1use crate::{Radians, Vector};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
5pub struct Size<T = f32> {
6 pub width: T,
8 pub height: T,
10}
11
12impl<T> Size<T> {
13 pub const fn new(width: T, height: T) -> Self {
15 Size { width, height }
16 }
17}
18
19impl Size {
20 pub const ZERO: Size = Size::new(0., 0.);
22
23 pub const UNIT: Size = Size::new(1., 1.);
25
26 pub const INFINITY: Size = Size::new(f32::INFINITY, f32::INFINITY);
28
29 pub fn min(self, other: Self) -> Self {
31 Size {
32 width: self.width.min(other.width),
33 height: self.height.min(other.height),
34 }
35 }
36
37 pub fn max(self, other: Self) -> Self {
39 Size {
40 width: self.width.max(other.width),
41 height: self.height.max(other.height),
42 }
43 }
44
45 pub fn expand(self, other: impl Into<Size>) -> Self {
47 let other = other.into();
48
49 Size {
50 width: self.width + other.width,
51 height: self.height + other.height,
52 }
53 }
54
55 pub fn rotate(self, rotation: Radians) -> Size {
58 let radians = f32::from(rotation);
59
60 Size {
61 width: (self.width * radians.cos()).abs()
62 + (self.height * radians.sin()).abs(),
63 height: (self.width * radians.sin()).abs()
64 + (self.height * radians.cos()).abs(),
65 }
66 }
67}
68
69impl<T> From<[T; 2]> for Size<T> {
70 fn from([width, height]: [T; 2]) -> Self {
71 Size { width, height }
72 }
73}
74
75impl<T> From<(T, T)> for Size<T> {
76 fn from((width, height): (T, T)) -> Self {
77 Self { width, height }
78 }
79}
80
81impl<T> From<Vector<T>> for Size<T> {
82 fn from(vector: Vector<T>) -> Self {
83 Size {
84 width: vector.x,
85 height: vector.y,
86 }
87 }
88}
89
90impl<T> From<Size<T>> for [T; 2] {
91 fn from(size: Size<T>) -> Self {
92 [size.width, size.height]
93 }
94}
95
96impl<T> From<Size<T>> for Vector<T> {
97 fn from(size: Size<T>) -> Self {
98 Vector::new(size.width, size.height)
99 }
100}
101
102impl<T> std::ops::Add for Size<T>
103where
104 T: std::ops::Add<Output = T>,
105{
106 type Output = Size<T>;
107
108 fn add(self, rhs: Self) -> Self::Output {
109 Size {
110 width: self.width + rhs.width,
111 height: self.height + rhs.height,
112 }
113 }
114}
115
116impl<T> std::ops::Sub for Size<T>
117where
118 T: std::ops::Sub<Output = T>,
119{
120 type Output = Size<T>;
121
122 fn sub(self, rhs: Self) -> Self::Output {
123 Size {
124 width: self.width - rhs.width,
125 height: self.height - rhs.height,
126 }
127 }
128}
129
130impl<T> std::ops::Mul<T> for Size<T>
131where
132 T: std::ops::Mul<Output = T> + Copy,
133{
134 type Output = Size<T>;
135
136 fn mul(self, rhs: T) -> Self::Output {
137 Size {
138 width: self.width * rhs,
139 height: self.height * rhs,
140 }
141 }
142}
143
144impl<T> std::ops::Mul<Vector<T>> for Size<T>
145where
146 T: std::ops::Mul<Output = T> + Copy,
147{
148 type Output = Size<T>;
149
150 fn mul(self, scale: Vector<T>) -> Self::Output {
151 Size {
152 width: self.width * scale.x,
153 height: self.height * scale.y,
154 }
155 }
156}