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