ttf_view/types/
uint24mod.rs1use crate::util::impl_fmt_with;
2
3#[derive(Copy, Hash)]
4#[derive_const(Clone, PartialEq, Eq, PartialOrd, Ord)]
5#[repr(transparent)]
6pub struct uint24([u8; 3]);
7
8impl uint24 {
9 pub const BITS: u32 = 24;
10 pub const MIN: Self = Self::new(0x000000).unwrap();
11 pub const MAX: Self = Self::new(0xFFFFFF).unwrap();
12
13 pub const fn new(num: u32) -> Option<Self> {
14 if num <= 0xFFFFFF { Some(unsafe { Self::new_unchecked(num) }) } else { None }
15 }
16 pub const unsafe fn new_unchecked(num: u32) -> Self {
17 debug_assert!(num <= 0xFFFFFF);
18 let buf = num.to_be_bytes();
19 Self(*buf.last_chunk::<3>().unwrap())
20 }
21
22 pub const fn from_be_bytes(bytes: [u8; 3]) -> Self {
23 Self(bytes)
24 }
25 pub const fn to_be_bytes(self) -> [u8; 3] {
26 self.0
27 }
28
29 pub const fn get(&self) -> u32 {
30 let mut buf = [0; 4];
31 buf[1..].copy_from_slice(&self.0);
32 u32::from_be_bytes(buf)
33 }
34}
35
36impl_fmt_with! {
37 Debug, Display, Binary, Octal, LowerHex, UpperHex, LowerExp, UpperExp:
38 |this: &uint24, f| this.get().fmt(f)
39}
40
41#[allow(clippy::derivable_impls)]
43const impl Default for uint24 {
44 fn default() -> Self {
45 Self([0; 3])
46 }
47}
48
49const impl PartialEq<u32> for uint24 {
50 fn eq(&self, other: &u32) -> bool {
51 self.get().eq(other)
52 }
53}
54const impl PartialOrd<u32> for uint24 {
55 fn partial_cmp(&self, other: &u32) -> Option<std::cmp::Ordering> {
56 Some(self.get().cmp(other))
57 }
58}
59
60const impl std::str::FromStr for uint24 {
61 type Err = ();
62 fn from_str(s: &str) -> Result<Self, Self::Err> {
63 u32::from_str(s).or(Err(())).and_then(Self::try_from)
64 }
65}
66const impl TryFrom<u32> for uint24 {
67 type Error = ();
68 fn try_from(value: u32) -> Result<Self, Self::Error> {
69 Self::new(value).ok_or(())
70 }
71}
72const impl From<uint24> for u32 {
73 fn from(value: uint24) -> Self {
74 value.get()
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn conv() {
84 assert_eq!(uint24::new(0).unwrap(), 0);
85 assert_eq!(uint24::new(27).unwrap(), 27);
86 assert_eq!(uint24::new(256).unwrap(), 256);
87 assert_eq!(uint24::new(0xFFFFFF).unwrap(), 0xFFFFFF);
88 assert_eq!(uint24::new(0x01000000), None);
89 assert_eq!(uint24::new(0xFFFFFFFF), None);
90 }
91}