1use crate::{
2 DeserializationError, SerializationError, SerializerConfig,
3 utils::{ensure_size, slice},
4};
5
6pub fn write_zigzag<T, const S: usize, U : Clone>(
7 val: T,
8 bytes: &mut Vec<u8>,
9 config: &mut SerializerConfig<U>,
10) -> Result<(), SerializationError>
11where
12 T: ZigZag,
13 T::Unsigned: FixedInt<S>,
14{
15 let encoded = val.to_unsigned();
16 encoded.write(bytes, config)
17}
18
19pub fn read_zigzag<T, const S: usize, U : Clone>(
20 bytes: &[u8],
21 config: &mut SerializerConfig<U>,
22) -> Result<T, DeserializationError>
23where
24 T: ZigZag,
25 T::Unsigned: FixedInt<S>,
26{
27 let raw = T::Unsigned::read(bytes, config)?;
28 Ok(T::to_signed(raw))
29}
30
31pub trait FixedInt<const S: usize>: Sized {
33 fn serialize(self) -> [u8; S];
34 fn deserialize(bytes: &[u8]) -> Self;
35
36 fn write<U : Clone>(
37 self,
38 bytes: &mut Vec<u8>,
39 config: &mut SerializerConfig<U>,
40 ) -> Result<(), SerializationError> {
41 config.reset_bits(false);
42 bytes.extend_from_slice(&self.serialize());
43 config.pos += S;
44 Ok(())
45 }
46
47 fn read<U : Clone>(
48 bytes: &[u8],
49 config: &mut SerializerConfig<U>,
50 ) -> Result<Self, DeserializationError> {
51 config.reset_bits(true);
52 ensure_size(config, bytes, S)?;
53 Ok(Self::deserialize(slice(config, bytes, S, true)?))
54 }
55}
56
57impl FixedInt<1> for u8 {
58 fn serialize(self) -> [u8; 1] {
59 self.to_be_bytes()
60 }
61
62 fn deserialize(bytes: &[u8]) -> Self {
63 u8::from_be_bytes(bytes.try_into().unwrap())
64 .try_into()
65 .unwrap()
66 }
67}
68
69impl FixedInt<2> for u16 {
70 fn serialize(self) -> [u8; 2] {
71 self.to_be_bytes()
72 }
73
74 fn deserialize(bytes: &[u8]) -> Self {
75 u16::from_be_bytes(bytes.try_into().unwrap())
76 .try_into()
77 .unwrap()
78 }
79}
80
81impl FixedInt<4> for u32 {
82 fn serialize(self) -> [u8; 4] {
83 self.to_be_bytes()
84 }
85
86 fn deserialize(bytes: &[u8]) -> Self {
87 u32::from_be_bytes(bytes.try_into().unwrap())
88 .try_into()
89 .unwrap()
90 }
91}
92
93impl FixedInt<8> for u64 {
94 fn serialize(self) -> [u8; 8] {
95 self.to_be_bytes()
96 }
97
98 fn deserialize(bytes: &[u8]) -> Self {
99 u64::from_be_bytes(bytes.try_into().unwrap())
100 .try_into()
101 .unwrap()
102 }
103}
104
105impl FixedInt<16> for u128 {
106 fn serialize(self) -> [u8; 16] {
107 self.to_be_bytes()
108 }
109
110 fn deserialize(bytes: &[u8]) -> Self {
111 u128::from_be_bytes(bytes.try_into().unwrap())
112 .try_into()
113 .unwrap()
114 }
115}
116
117pub trait ZigZag {
119 type Unsigned;
120
121 fn to_unsigned(self) -> Self::Unsigned;
122 fn to_signed(n: Self::Unsigned) -> Self;
123}
124
125impl ZigZag for i8 {
126 type Unsigned = u8;
127 fn to_unsigned(self) -> u8 {
128 ((self << 1) ^ (self >> 7)) as u8
129 }
130 fn to_signed(n: u8) -> i8 {
131 ((n >> 1) as i8) ^ -((n & 1) as i8)
132 }
133}
134
135impl ZigZag for i16 {
136 type Unsigned = u16;
137 fn to_unsigned(self) -> u16 {
138 ((self << 1) ^ (self >> 15)) as u16
139 }
140 fn to_signed(n: u16) -> i16 {
141 ((n >> 1) as i16) ^ -((n & 1) as i16)
142 }
143}
144
145impl ZigZag for i32 {
146 type Unsigned = u32;
147 fn to_unsigned(self) -> u32 {
148 ((self << 1) ^ (self >> 31)) as u32
149 }
150 fn to_signed(n: u32) -> i32 {
151 ((n >> 1) as i32) ^ -((n & 1) as i32)
152 }
153}
154
155impl ZigZag for i64 {
156 type Unsigned = u64;
157 fn to_unsigned(self) -> u64 {
158 ((self << 1) ^ (self >> 63)) as u64
159 }
160 fn to_signed(n: u64) -> i64 {
161 ((n >> 1) as i64) ^ -((n & 1) as i64)
162 }
163}
164
165impl ZigZag for i128 {
166 type Unsigned = u128;
167 fn to_unsigned(self) -> u128 {
168 ((self << 1) ^ (self >> 127)) as u128
169 }
170 fn to_signed(n: u128) -> i128 {
171 ((n >> 1) as i128) ^ -((n & 1) as i128)
172 }
173}
174
175#[cfg(test)]
176mod tests {
177 use super::*;
178 macro_rules! zigzag_test {
179 ($name:ident, $ty:ty, $unsigned:ty, $val:expr, $expected:expr) => {
180 #[test]
181 fn $name() {
182 let val: $ty = $val;
183 let encoded: $unsigned = val.to_unsigned();
184 assert_eq!(encoded, $expected, "ZigZag encoding failed for {}", val);
185 let decoded: $ty = <$ty>::to_signed(encoded);
186 assert_eq!(decoded, val, "ZigZag decoding failed for {}", val);
187 }
188 };
189 }
190
191 zigzag_test!(
192 zigzag_i16_pos,
193 i16,
194 u16,
195 0b0000_0000_0000_0010,
196 0b0000_0000_0000_0100
197 );
198 zigzag_test!(
199 zigzag_i16_neg,
200 i16,
201 u16,
202 -0b0000_0000_0000_0010,
203 0b0000_0000_0000_0011
204 );
205 zigzag_test!(
206 zigzag_i32_pos,
207 i32,
208 u32,
209 0b0000_0000_0000_0000_0000_0000_0000_0010,
210 0b0000_0000_0000_0000_0000_0000_0000_0100
211 );
212 zigzag_test!(
213 zigzag_i32_neg,
214 i32,
215 u32,
216 -0b0000_0000_0000_0000_0000_0000_0000_0010,
217 0b0000_0000_0000_0000_0000_0000_0000_0011
218 );
219 zigzag_test!(zigzag_i64_pos, i64, u64, 0b10, 0b100);
220 zigzag_test!(zigzag_i64_neg, i64, u64, -0b10, 0b11);
221 zigzag_test!(zigzag_i128_pos, i128, u128, 0b10, 0b100);
222 zigzag_test!(zigzag_i128_neg, i128, u128, -0b10, 0b11);
223
224 macro_rules! fixedint_test {
225 ($name:ident, $ty:ty, $val:expr, $bytes:expr) => {
226 #[test]
227 fn $name() {
228 let val: $ty = $val;
229 let serialized = val.serialize();
230 assert_eq!(serialized, $bytes, "FixedInt serialize failed for {}", val);
231 let deserialized = <$ty>::deserialize(&serialized);
232 assert_eq!(
233 deserialized, val,
234 "FixedInt deserialize failed for {:?}",
235 serialized
236 );
237 }
238 };
239 }
240
241 fixedint_test!(fixedint_u16, u16, 0b1010_1010_1010_1010, [0b1010_1010; 2]);
242 fixedint_test!(
243 fixedint_u32,
244 u32,
245 0b1010_1010_1010_1010_1010_1010_1010_1010,
246 [0b1010_1010; 4]
247 );
248 fixedint_test!(
249 fixedint_u64,
250 u64,
251 0b1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010,
252 [0b1010_1010; 8]
253 );
254 fixedint_test!(fixedint_u128, u128, 0b1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010, [0b1010_1010; 16]);
255
256 #[test]
257 fn test_write_read_zigzag_i32() {
258 let mut bytes = Vec::new();
259 let mut config = SerializerConfig::new(None);
260 let val: i32 = -123;
261 write_zigzag::<i32, 4, ()>(val, &mut bytes, &mut config).unwrap();
262 let mut config = SerializerConfig::new(None);
263 let decoded = read_zigzag::<i32, 4, ()>(&bytes, &mut config).unwrap();
264 assert_eq!(decoded, val);
265 }
266
267 #[test]
268 fn test_write_read_zigzag_i64() {
269 let mut bytes = Vec::new();
270 let mut config = SerializerConfig::new(None);
271 let val: i64 = 456789;
272 write_zigzag::<i64, 8, ()>(val, &mut bytes, &mut config).unwrap();
273 let mut config = SerializerConfig::new(None);
274 let decoded = read_zigzag::<i64, 8, ()>(&bytes, &mut config).unwrap();
275 assert_eq!(decoded, val);
276 }
277
278 #[test]
279 fn test_write_read_fixedint_u32() {
280 let mut bytes = Vec::new();
281 let mut config = SerializerConfig::<()>::new(None);
282 let val: u32 = 0b1010_1010_1010_1010_1010_1010_1010_1010;
283 val.write(&mut bytes, &mut config).unwrap();
284 let mut config = SerializerConfig::<()>::new(None);
285 let decoded = u32::read(&bytes, &mut config).unwrap();
286 assert_eq!(decoded, val);
287 }
288
289 #[test]
290 fn test_write_read_fixedint_u128() {
291 let mut bytes = Vec::new();
292 let mut config = SerializerConfig::<()>::new(None);
293 let val: u128 = 0b1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010;
294 val.write(&mut bytes, &mut config).unwrap();
295 let mut config = SerializerConfig::<()>::new(None);
296 let decoded = u128::read(&bytes, &mut config).unwrap();
297 assert_eq!(decoded, val);
298 }
299
300 #[test]
301 fn test_read_fixedint_with_offset_bits() {
302 let bytes = [0b0101_0101, 7];
303 let mut config = SerializerConfig::<()>::new(None);
304 config.bits = 4;
305 let decoded = u8::read(&bytes, &mut config).unwrap();
306 assert_eq!(decoded, 7);
307 }
308}