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
122#[cfg(test)]
123mod tests {
124 use crate::encoding::fixed_int::FixedInt;
125
126 macro_rules! fixedint_test {
127 ($name:ident, $ty:ty, $val:expr, $bytes:expr) => {
128 #[test]
129 fn $name() {
130 let val: $ty = $val;
131 let serialized = val.serialize();
132 assert_eq!(serialized, $bytes, "FixedInt serialize failed for {}", val);
133 let deserialized = <$ty>::deserialize(&serialized);
134 assert_eq!(
135 deserialized, val,
136 "FixedInt deserialize failed for {:?}",
137 serialized
138 );
139 }
140 };
141 }
142
143 fixedint_test!(fixedint_u16, u16, 0b1010_1010_1010_1010, [0b1010_1010; 2]);
144 fixedint_test!(
145 fixedint_u32,
146 u32,
147 0b1010_1010_1010_1010_1010_1010_1010_1010,
148 [0b1010_1010; 4]
149 );
150 fixedint_test!(
151 fixedint_u64,
152 u64,
153 0b1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010,
154 [0b1010_1010; 8]
155 );
156 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]);
157}