binary_codec/encoding/
fixed_int.rs1use crate::encoding::zigzag::ZigZag;
2
3pub trait FixedInt<const S: usize>: Sized {
5 fn serialize(self) -> [u8; S];
7
8 fn deserialize(bytes: &[u8]) -> Self;
10}
11
12impl FixedInt<1> for u8 {
13 fn serialize(self) -> [u8; 1] {
14 self.to_be_bytes()
15 }
16
17 fn deserialize(bytes: &[u8]) -> Self {
18 u8::from_be_bytes(bytes.try_into().unwrap())
19 .try_into()
20 .unwrap()
21 }
22}
23
24impl FixedInt<1> for i8 {
25 fn serialize(self) -> [u8; 1] {
26 FixedInt::serialize(self.to_unsigned())
27 }
28
29 fn deserialize(bytes: &[u8]) -> Self {
30 ZigZag::to_signed(FixedInt::deserialize(bytes))
31 }
32}
33
34impl FixedInt<2> for u16 {
35 fn serialize(self) -> [u8; 2] {
36 self.to_be_bytes()
37 }
38
39 fn deserialize(bytes: &[u8]) -> Self {
40 u16::from_be_bytes(bytes.try_into().unwrap())
41 .try_into()
42 .unwrap()
43 }
44}
45
46impl FixedInt<2> for i16 {
47 fn serialize(self) -> [u8; 2] {
48 FixedInt::serialize(self.to_unsigned())
49 }
50
51 fn deserialize(bytes: &[u8]) -> Self {
52 ZigZag::to_signed(FixedInt::deserialize(bytes))
53 }
54}
55
56impl FixedInt<4> for u32 {
57 fn serialize(self) -> [u8; 4] {
58 self.to_be_bytes()
59 }
60
61 fn deserialize(bytes: &[u8]) -> Self {
62 u32::from_be_bytes(bytes.try_into().unwrap())
63 .try_into()
64 .unwrap()
65 }
66}
67
68impl FixedInt<4> for i32 {
69 fn serialize(self) -> [u8; 4] {
70 FixedInt::serialize(self.to_unsigned())
71 }
72
73 fn deserialize(bytes: &[u8]) -> Self {
74 ZigZag::to_signed(FixedInt::deserialize(bytes))
75 }
76}
77
78impl FixedInt<8> for u64 {
79 fn serialize(self) -> [u8; 8] {
80 self.to_be_bytes()
81 }
82
83 fn deserialize(bytes: &[u8]) -> Self {
84 u64::from_be_bytes(bytes.try_into().unwrap())
85 .try_into()
86 .unwrap()
87 }
88}
89
90impl FixedInt<8> for i64 {
91 fn serialize(self) -> [u8; 8] {
92 FixedInt::serialize(self.to_unsigned())
93 }
94
95 fn deserialize(bytes: &[u8]) -> Self {
96 ZigZag::to_signed(FixedInt::deserialize(bytes))
97 }
98}
99
100impl FixedInt<16> for u128 {
101 fn serialize(self) -> [u8; 16] {
102 self.to_be_bytes()
103 }
104
105 fn deserialize(bytes: &[u8]) -> Self {
106 u128::from_be_bytes(bytes.try_into().unwrap())
107 .try_into()
108 .unwrap()
109 }
110}
111
112impl FixedInt<16> for i128 {
113 fn serialize(self) -> [u8; 16] {
114 FixedInt::serialize(self.to_unsigned())
115 }
116
117 fn deserialize(bytes: &[u8]) -> Self {
118 ZigZag::to_signed(FixedInt::deserialize(bytes))
119 }
120}
121
122impl FixedInt<4> for f32 {
123 fn serialize(self) -> [u8; 4] {
124 self.to_be_bytes()
125 }
126
127 fn deserialize(bytes: &[u8]) -> Self {
128 f32::from_be_bytes(bytes.try_into().unwrap())
129 }
130}
131
132impl FixedInt<8> for f64 {
133 fn serialize(self) -> [u8; 8] {
134 self.to_be_bytes()
135 }
136
137 fn deserialize(bytes: &[u8]) -> Self {
138 f64::from_be_bytes(bytes.try_into().unwrap())
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use crate::encoding::fixed_int::FixedInt;
145
146 macro_rules! fixedint_test {
147 ($name:ident, $ty:ty, $val:expr, $bytes:expr) => {
148 #[test]
149 fn $name() {
150 let val: $ty = $val;
151 let serialized = val.serialize();
152 assert_eq!(serialized, $bytes, "FixedInt serialize failed for {}", val);
153 let deserialized = <$ty>::deserialize(&serialized);
154 assert_eq!(
155 deserialized, val,
156 "FixedInt deserialize failed for {:?}",
157 serialized
158 );
159 }
160 };
161 }
162
163 fixedint_test!(fixedint_u16, u16, 0b1010_1010_1010_1010, [0b1010_1010; 2]);
164 fixedint_test!(
165 fixedint_u32,
166 u32,
167 0b1010_1010_1010_1010_1010_1010_1010_1010,
168 [0b1010_1010; 4]
169 );
170 fixedint_test!(
171 fixedint_u64,
172 u64,
173 0b1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010,
174 [0b1010_1010; 8]
175 );
176 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]);
177}