1#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
12#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
13pub struct CornerRadius {
14 pub nw: u8,
16
17 pub ne: u8,
19
20 pub sw: u8,
22
23 pub se: u8,
25}
26
27impl Default for CornerRadius {
28 #[inline]
29 fn default() -> Self {
30 Self::ZERO
31 }
32}
33
34impl From<u8> for CornerRadius {
35 #[inline]
36 fn from(radius: u8) -> Self {
37 Self::same(radius)
38 }
39}
40
41impl From<f32> for CornerRadius {
42 #[inline]
43 fn from(radius: f32) -> Self {
44 Self::same(radius.round() as u8)
45 }
46}
47
48impl CornerRadius {
49 pub const ZERO: Self = Self {
51 nw: 0,
52 ne: 0,
53 sw: 0,
54 se: 0,
55 };
56
57 #[inline]
59 pub const fn same(radius: u8) -> Self {
60 Self {
61 nw: radius,
62 ne: radius,
63 sw: radius,
64 se: radius,
65 }
66 }
67
68 #[inline]
70 pub fn is_same(self) -> bool {
71 self.nw == self.ne && self.nw == self.sw && self.nw == self.se
72 }
73
74 #[inline]
76 pub fn at_least(self, min: u8) -> Self {
77 Self {
78 nw: self.nw.max(min),
79 ne: self.ne.max(min),
80 sw: self.sw.max(min),
81 se: self.se.max(min),
82 }
83 }
84
85 #[inline]
87 pub fn at_most(self, max: u8) -> Self {
88 Self {
89 nw: self.nw.min(max),
90 ne: self.ne.min(max),
91 sw: self.sw.min(max),
92 se: self.se.min(max),
93 }
94 }
95
96 pub fn average(&self) -> f32 {
98 (self.nw as f32 + self.ne as f32 + self.sw as f32 + self.se as f32) / 4.0
99 }
100}
101
102impl std::ops::Add for CornerRadius {
103 type Output = Self;
104 #[inline]
105 fn add(self, rhs: Self) -> Self {
106 Self {
107 nw: self.nw.saturating_add(rhs.nw),
108 ne: self.ne.saturating_add(rhs.ne),
109 sw: self.sw.saturating_add(rhs.sw),
110 se: self.se.saturating_add(rhs.se),
111 }
112 }
113}
114
115impl std::ops::Add<u8> for CornerRadius {
116 type Output = Self;
117 #[inline]
118 fn add(self, rhs: u8) -> Self {
119 Self {
120 nw: self.nw.saturating_add(rhs),
121 ne: self.ne.saturating_add(rhs),
122 sw: self.sw.saturating_add(rhs),
123 se: self.se.saturating_add(rhs),
124 }
125 }
126}
127
128impl std::ops::AddAssign for CornerRadius {
129 #[inline]
130 fn add_assign(&mut self, rhs: Self) {
131 *self = Self {
132 nw: self.nw.saturating_add(rhs.nw),
133 ne: self.ne.saturating_add(rhs.ne),
134 sw: self.sw.saturating_add(rhs.sw),
135 se: self.se.saturating_add(rhs.se),
136 };
137 }
138}
139
140impl std::ops::AddAssign<u8> for CornerRadius {
141 #[inline]
142 fn add_assign(&mut self, rhs: u8) {
143 *self = Self {
144 nw: self.nw.saturating_add(rhs),
145 ne: self.ne.saturating_add(rhs),
146 sw: self.sw.saturating_add(rhs),
147 se: self.se.saturating_add(rhs),
148 };
149 }
150}
151
152impl std::ops::Sub for CornerRadius {
153 type Output = Self;
154 #[inline]
155 fn sub(self, rhs: Self) -> Self {
156 Self {
157 nw: self.nw.saturating_sub(rhs.nw),
158 ne: self.ne.saturating_sub(rhs.ne),
159 sw: self.sw.saturating_sub(rhs.sw),
160 se: self.se.saturating_sub(rhs.se),
161 }
162 }
163}
164
165impl std::ops::Sub<u8> for CornerRadius {
166 type Output = Self;
167 #[inline]
168 fn sub(self, rhs: u8) -> Self {
169 Self {
170 nw: self.nw.saturating_sub(rhs),
171 ne: self.ne.saturating_sub(rhs),
172 sw: self.sw.saturating_sub(rhs),
173 se: self.se.saturating_sub(rhs),
174 }
175 }
176}
177
178impl std::ops::SubAssign for CornerRadius {
179 #[inline]
180 fn sub_assign(&mut self, rhs: Self) {
181 *self = Self {
182 nw: self.nw.saturating_sub(rhs.nw),
183 ne: self.ne.saturating_sub(rhs.ne),
184 sw: self.sw.saturating_sub(rhs.sw),
185 se: self.se.saturating_sub(rhs.se),
186 };
187 }
188}
189
190impl std::ops::SubAssign<u8> for CornerRadius {
191 #[inline]
192 fn sub_assign(&mut self, rhs: u8) {
193 *self = Self {
194 nw: self.nw.saturating_sub(rhs),
195 ne: self.ne.saturating_sub(rhs),
196 sw: self.sw.saturating_sub(rhs),
197 se: self.se.saturating_sub(rhs),
198 };
199 }
200}
201
202impl std::ops::Div<f32> for CornerRadius {
203 type Output = Self;
204 #[inline]
205 fn div(self, rhs: f32) -> Self {
206 Self {
207 nw: (self.nw as f32 / rhs) as u8,
208 ne: (self.ne as f32 / rhs) as u8,
209 sw: (self.sw as f32 / rhs) as u8,
210 se: (self.se as f32 / rhs) as u8,
211 }
212 }
213}
214
215impl std::ops::DivAssign<f32> for CornerRadius {
216 #[inline]
217 fn div_assign(&mut self, rhs: f32) {
218 *self = Self {
219 nw: (self.nw as f32 / rhs) as u8,
220 ne: (self.ne as f32 / rhs) as u8,
221 sw: (self.sw as f32 / rhs) as u8,
222 se: (self.se as f32 / rhs) as u8,
223 };
224 }
225}
226
227impl std::ops::Mul<f32> for CornerRadius {
228 type Output = Self;
229 #[inline]
230 fn mul(self, rhs: f32) -> Self {
231 Self {
232 nw: (self.nw as f32 * rhs) as u8,
233 ne: (self.ne as f32 * rhs) as u8,
234 sw: (self.sw as f32 * rhs) as u8,
235 se: (self.se as f32 * rhs) as u8,
236 }
237 }
238}
239
240impl std::ops::MulAssign<f32> for CornerRadius {
241 #[inline]
242 fn mul_assign(&mut self, rhs: f32) {
243 *self = Self {
244 nw: (self.nw as f32 * rhs) as u8,
245 ne: (self.ne as f32 * rhs) as u8,
246 sw: (self.sw as f32 * rhs) as u8,
247 se: (self.se as f32 * rhs) as u8,
248 };
249 }
250}