apple_cf/utils/
four_char_code.rs1use std::fmt;
7use std::str::FromStr;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
25pub struct FourCharCode(u32);
26
27impl FourCharCode {
28 #[inline]
39 #[must_use]
40 pub const fn from_bytes(bytes: [u8; 4]) -> Self {
41 Self(u32::from_be_bytes(bytes))
42 }
43
44 #[must_use]
46 pub fn from_slice(bytes: &[u8]) -> Option<Self> {
47 if bytes.len() != 4 {
48 return None;
49 }
50
51 let code = u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
52 Some(Self(code))
53 }
54
55 #[inline]
67 #[must_use]
68 pub const fn as_u32(self) -> u32 {
69 self.0
70 }
71
72 #[inline]
74 #[must_use]
75 pub const fn as_bytes(self) -> [u8; 4] {
76 self.0.to_be_bytes()
77 }
78
79 #[inline]
81 #[must_use]
82 pub const fn from_u32(value: u32) -> Self {
83 Self(value)
84 }
85
86 #[inline]
88 #[must_use]
89 pub const fn equals(self, other: Self) -> bool {
90 self.0 == other.0
91 }
92
93 #[must_use]
95 pub fn display(self) -> String {
96 let bytes = self.0.to_be_bytes();
97 String::from_utf8_lossy(&bytes).to_string()
98 }
99}
100
101impl FromStr for FourCharCode {
102 type Err = &'static str;
103
104 fn from_str(s: &str) -> Result<Self, Self::Err> {
105 if s.len() != 4 {
106 return Err("FourCharCode must be exactly 4 characters");
107 }
108 if !s.is_ascii() {
109 return Err("FourCharCode must contain only ASCII characters");
110 }
111
112 let bytes = s.as_bytes();
113 let code = u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
114 Ok(Self(code))
115 }
116}
117
118impl From<u32> for FourCharCode {
119 fn from(value: u32) -> Self {
120 Self(value)
121 }
122}
123
124impl From<FourCharCode> for u32 {
125 fn from(code: FourCharCode) -> Self {
126 code.0
127 }
128}
129
130impl fmt::Display for FourCharCode {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 write!(f, "{}", self.display())
133 }
134}