rkg_utils/
byte_handler.rs1#[derive(thiserror::Error, Debug)]
2pub enum ByteHandlerError {
3 #[error("Couldn't convert type to ByteHandler: Too Long")]
5 ConversionErrorTooLong,
6}
7
8#[repr(C)]
10#[derive(Clone, Copy)]
11pub(crate) union ByteHandler {
12 dword: u32,
13 words: [u16; 2],
14 bytes: [u8; 4],
15}
16
17impl ByteHandler {
18 pub const fn copy_dword(self) -> u32 {
19 unsafe { self.dword }
20 }
21
22 pub const fn copy_word(self, idx: usize) -> u16 {
23 if idx > 1 {
24 return 0;
25 }
26
27 #[cfg(target_endian = "little")]
28 let idx = 1 - idx;
29
30 unsafe { self.words[idx] }
31 }
32
33 pub const fn copy_byte(self, idx: usize) -> u8 {
34 if idx > 3 {
35 return 0;
36 }
37
38 #[cfg(target_endian = "little")]
39 let idx = 3 - idx;
40
41 unsafe { self.bytes[idx] }
42 }
43
44 pub const fn shift_right(&mut self, d: u8) {
45 unsafe {
46 self.dword >>= d;
47 }
48 }
49
50 pub const fn shift_left(&mut self, d: u8) {
51 unsafe {
52 self.dword <<= d;
53 }
54 }
55
56 pub const fn read_bool(&self, d: u8) -> bool {
58 if d >= 32 {
59 return false;
60 }
61
62 #[cfg(target_endian = "little")]
63 return (unsafe { self.dword } & (1u32 << ((d % 8) + 8 * (3 - (d / 8))))) != 0;
64
65 #[cfg(target_endian = "big")]
66 return (unsafe { self.dword } & (1u32 << d)) != 0;
67 }
68}
69
70impl From<[u8; 4]> for ByteHandler {
71 fn from(value: [u8; 4]) -> Self {
72 ByteHandler {
73 #[cfg(target_endian = "big")]
74 bytes: [value[0], value[1], value[2], value[3]],
75 #[cfg(target_endian = "little")]
76 bytes: [value[3], value[2], value[1], value[0]],
77 }
78 }
79}
80
81impl From<[u8; 3]> for ByteHandler {
82 fn from(value: [u8; 3]) -> Self {
83 ByteHandler {
84 #[cfg(target_endian = "big")]
85 bytes: [value[0], value[1], value[2], 0],
86 #[cfg(target_endian = "little")]
87 bytes: [0, value[2], value[1], value[0]],
88 }
89 }
90}
91
92impl From<[u8; 2]> for ByteHandler {
93 fn from(value: [u8; 2]) -> Self {
94 ByteHandler {
95 #[cfg(target_endian = "big")]
96 bytes: [value[0], value[1], 0, 0],
97 #[cfg(target_endian = "little")]
98 bytes: [0, 0, value[1], value[0]],
99 }
100 }
101}
102
103impl From<u8> for ByteHandler {
104 fn from(value: u8) -> Self {
105 ByteHandler {
106 #[cfg(target_endian = "big")]
107 bytes: [value, 0, 0, 0],
108 #[cfg(target_endian = "little")]
109 bytes: [0, 0, 0, value],
110 }
111 }
112}
113
114impl From<u32> for ByteHandler {
115 fn from(value: u32) -> Self {
116 ByteHandler { dword: value }
117 }
118}
119
120impl From<[u16; 2]> for ByteHandler {
121 fn from(value: [u16; 2]) -> Self {
122 ByteHandler {
123 #[cfg(target_endian = "big")]
124 words: [value[0], value[1]],
125 #[cfg(target_endian = "little")]
126 words: [value[1], value[0]],
127 }
128 }
129}
130
131impl From<u16> for ByteHandler {
132 fn from(value: u16) -> Self {
133 ByteHandler {
134 #[cfg(target_endian = "big")]
135 words: [value, 0],
136 #[cfg(target_endian = "little")]
137 words: [0, value],
138 }
139 }
140}
141
142macro_rules! shorten_syntax {
143 ($num:literal $value:ident $type:ty) => {
144 Ok(From::from(unsafe {
145 TryInto::<[$type; $num]>::try_into($value).unwrap_unchecked()
146 }))
147 };
148}
149
150impl TryFrom<&[u8]> for ByteHandler {
151 type Error = ByteHandlerError;
152
153 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
154 match value.len() {
155 0 => Ok(From::from(0u32)),
156 1 => Ok(From::from(value[0])),
157 2 => shorten_syntax!(2 value u8),
158 3 => shorten_syntax!(3 value u8),
159 4 => shorten_syntax!(4 value u8),
160 _ => Err(ByteHandlerError::ConversionErrorTooLong),
161 }
162 }
163}
164
165impl TryFrom<&[u16]> for ByteHandler {
166 type Error = ByteHandlerError;
167
168 fn try_from(value: &[u16]) -> Result<Self, Self::Error> {
169 match value.len() {
170 0 => Ok(From::from(0u32)),
171 1 => Ok(From::from(value[0])),
172 2 => shorten_syntax!(2 value u16),
173 _ => Err(ByteHandlerError::ConversionErrorTooLong),
174 }
175 }
176}
177
178pub(crate) trait FromByteHandler: Sized {
179 type Err;
180
181 fn from_byte_handler<T>(handler: T) -> Result<Self, Self::Err>
182 where
183 T: TryInto<ByteHandler>,
184 Self::Err: From<T::Error>;
185}