ttf_view/types/
uint24mod.rs1use crate::util::impl_fmt_with;
2
3#[derive(Copy, Hash)]
20#[derive_const(Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
21#[repr(transparent)]
22pub struct u24(u32);
23
24impl u24 {
25 pub const BITS: u32 = 24;
34 pub const MIN: Self = Self(0x000000);
43 pub const MAX: Self = Self(0xFFFFFF);
52
53 pub const fn new(num: u32) -> Option<Self> {
67 if num <= Self::MAX.0 { Some(Self(num)) } else { None }
68 }
69 pub const fn new_saturating(num: u32) -> Self {
83 Self(num.min(Self::MAX.0))
84 }
85 pub const fn new_truncating(num: u32) -> Self {
99 Self(num & Self::MAX.0)
100 }
101
102 pub const fn from_be_bytes(bytes: [u8; 3]) -> Self {
113 let [a, b, c] = bytes;
114 Self(u32::from_be_bytes([0, a, b, c]))
115 }
116 pub const fn to_be_bytes(self) -> [u8; 3] {
127 *self.0.to_be_bytes().last_chunk().unwrap()
128 }
129
130 pub const fn get(self) -> u32 {
141 self.0
142 }
143
144 pub const fn wrapping_neg(self) -> Self {
145 Self(self.0.wrapping_neg() & Self::MAX.0)
146 }
147 pub const fn wrapping_add(self, rhs: Self) -> Self {
148 Self(self.0.wrapping_add(rhs.0) & Self::MAX.0)
149 }
150 pub const fn wrapping_sub(self, rhs: Self) -> Self {
151 Self(self.0.wrapping_sub(rhs.0) & Self::MAX.0)
152 }
153 pub const fn wrapping_mul(self, rhs: Self) -> Self {
154 Self(self.0.wrapping_mul(rhs.0) & Self::MAX.0)
155 }
156 pub const fn wrapping_div(self, rhs: Self) -> Self {
160 Self(self.0.wrapping_div(rhs.0))
161 }
162 pub const fn wrapping_rem(self, rhs: Self) -> Self {
166 Self(self.0.wrapping_rem(rhs.0))
167 }
168
169 pub const fn saturating_add(self, rhs: Self) -> Self {
170 Self(self.0.wrapping_add(rhs.0).min(Self::MAX.0))
171 }
172 pub const fn saturating_sub(self, rhs: Self) -> Self {
173 Self(self.0.saturating_sub(rhs.0))
174 }
175 pub const fn saturating_mul(self, rhs: Self) -> Self {
176 Self(self.0.widening_mul(rhs.0).min(Self::MAX.0 as u64) as u32)
177 }
178 pub const fn saturating_div(self, rhs: Self) -> Self {
182 Self(self.0.saturating_div(rhs.0))
183 }
184
185 pub const fn checked_neg(self) -> Option<Self> {
186 self.0.checked_neg().map(Self)
187 }
188 pub const fn checked_add(self, rhs: Self) -> Option<Self> {
189 self.0.wrapping_add(rhs.0).try_into().ok()
190 }
191 pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
192 self.0.checked_sub(rhs.0).map(Self)
193 }
194 pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
195 self.0.widening_mul(rhs.0).try_into().ok()
196 }
197 pub const fn checked_div(self, rhs: Self) -> Option<Self> {
198 self.0.checked_div(rhs.0).map(Self)
199 }
200 pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
201 self.0.checked_rem(rhs.0).map(Self)
202 }
203}
204
205const impl std::ops::Add for u24 {
207 type Output = Self;
208 fn add(self, rhs: Self) -> Self::Output {
209 #[cfg(debug_assertions)]
210 return self.checked_add(rhs).expect("attempt to add with overflow");
211 #[cfg(not(debug_assertions))]
212 return self.wrapping_add(rhs);
213 }
214}
215const impl std::ops::Sub for u24 {
217 type Output = Self;
218 fn sub(self, rhs: Self) -> Self::Output {
219 #[cfg(debug_assertions)]
220 return self.checked_sub(rhs).expect("attempt to subtract with overflow");
221 #[cfg(not(debug_assertions))]
222 return self.wrapping_sub(rhs);
223 }
224}
225const impl std::ops::Mul for u24 {
227 type Output = Self;
228 fn mul(self, rhs: Self) -> Self::Output {
229 #[cfg(debug_assertions)]
230 return self.checked_mul(rhs).expect("attempt to multiply with overflow");
231 #[cfg(not(debug_assertions))]
232 return self.wrapping_mul(rhs);
233 }
234}
235const impl std::ops::Div for u24 {
241 type Output = Self;
242 fn div(self, rhs: Self) -> Self::Output {
243 #[cfg(debug_assertions)]
244 return self.checked_div(rhs).expect("attempt to divide by zero");
245 #[cfg(not(debug_assertions))]
246 return self.wrapping_div(rhs);
247 }
248}
249const impl std::ops::Rem for u24 {
255 type Output = Self;
256 fn rem(self, rhs: Self) -> Self::Output {
257 #[cfg(debug_assertions)]
258 return self
259 .checked_rem(rhs)
260 .expect("attempt to calculate the remainder with a divisor of zero");
261
262 #[cfg(not(debug_assertions))]
263 return self.wrapping_rem(rhs);
264 }
265}
266
267impl_fmt_with! {
268 Debug, Display, Binary, Octal, LowerHex, UpperHex, LowerExp, UpperExp:
269 |this: &u24| this.get()
270}
271
272const impl PartialEq<u32> for u24 {
273 fn eq(&self, other: &u32) -> bool {
274 self.get().eq(other)
275 }
276}
277const impl PartialOrd<u32> for u24 {
278 fn partial_cmp(&self, other: &u32) -> Option<std::cmp::Ordering> {
279 Some(self.get().cmp(other))
280 }
281}
282
283const impl std::str::FromStr for u24 {
284 type Err = ();
285 fn from_str(s: &str) -> Result<Self, Self::Err> {
286 u32::from_str(s).or(Err(())).and_then(Self::try_from)
287 }
288}
289
290const impl TryFrom<usize> for u24 {
291 type Error = ();
292 fn try_from(value: usize) -> Result<Self, Self::Error> {
293 value.try_into().ok().and_then(Self::new).ok_or(())
294 }
295}
296const impl TryFrom<u64> for u24 {
297 type Error = ();
298 fn try_from(value: u64) -> Result<Self, Self::Error> {
299 value.try_into().ok().and_then(Self::new).ok_or(())
300 }
301}
302const impl TryFrom<u32> for u24 {
303 type Error = ();
304 fn try_from(value: u32) -> Result<Self, Self::Error> {
305 Self::new(value).ok_or(())
306 }
307}
308const impl From<u16> for u24 {
309 fn from(value: u16) -> Self {
310 Self(value as u32)
311 }
312}
313const impl From<u8> for u24 {
314 fn from(value: u8) -> Self {
315 Self(value as u32)
316 }
317}
318
319const impl TryFrom<u24> for usize {
320 type Error = ();
321 fn try_from(value: u24) -> Result<Self, Self::Error> {
322 value.get().try_into().ok().ok_or(())
323 }
324}
325const impl From<u24> for u64 {
326 fn from(value: u24) -> Self {
327 value.get() as u64
328 }
329}
330const impl From<u24> for u32 {
331 fn from(value: u24) -> Self {
332 value.get()
333 }
334}
335const impl TryFrom<u24> for u16 {
336 type Error = ();
337 fn try_from(value: u24) -> Result<Self, Self::Error> {
338 value.get().try_into().ok().ok_or(())
339 }
340}
341const impl TryFrom<u24> for u8 {
342 type Error = ();
343 fn try_from(value: u24) -> Result<Self, Self::Error> {
344 value.get().try_into().ok().ok_or(())
345 }
346}