rustmeter_beacon_core/
varint.rs1pub trait ZigZag: Sized + Copy {
3 type Unsigned;
4
5 fn zigzag_encode(self) -> Self::Unsigned;
8
9 fn zigzag_decode(encoded: Self::Unsigned) -> Self;
11}
12
13macro_rules! impl_zigzag {
15 ($signed:ty, $unsigned:ty) => {
16 impl ZigZag for $signed {
17 type Unsigned = $unsigned;
18
19 #[inline(always)]
20 fn zigzag_encode(self) -> Self::Unsigned {
21 const BITS: u32 = <$signed>::BITS;
22 ((self << 1) ^ (self >> (BITS - 1))) as $unsigned
25 }
26
27 #[inline(always)]
28 fn zigzag_decode(encoded: Self::Unsigned) -> Self {
29 (encoded >> 1) as $signed ^ -((encoded & 1) as $signed)
32 }
33 }
34 };
35}
36
37impl_zigzag!(i8, u8);
39impl_zigzag!(i16, u16);
40impl_zigzag!(i32, u32);
41impl_zigzag!(i64, u64);
42impl_zigzag!(isize, usize);
43
44#[cfg(test)]
45mod tests {
46 use super::ZigZag;
47 #[test]
48 fn test_zigzag() {
49 let enc = (-1i8).zigzag_encode();
50 assert_eq!(enc, 1u8);
51 let dec = i8::zigzag_decode(enc);
52 assert_eq!(dec, -1i8);
53
54 let enc = (0i16).zigzag_encode();
55 assert_eq!(enc, 0u16);
56 let dec = i16::zigzag_decode(enc);
57 assert_eq!(dec, 0i16);
58
59 let enc = (1i32).zigzag_encode();
60 assert_eq!(enc, 2u32);
61 let dec = i32::zigzag_decode(enc);
62 assert_eq!(dec, 1i32);
63
64 let enc = (-12345i64).zigzag_encode();
65 assert_eq!(enc, 24689u64);
66 let dec = i64::zigzag_decode(enc);
67 assert_eq!(dec, -12345i64);
68 }
69}
70
71pub trait VarIntWritable: Copy + PartialOrd {
74 fn is_zero(self) -> bool;
76
77 fn low_7_bits(self) -> u8;
79
80 fn shr_7(&mut self);
82}
83
84macro_rules! impl_varint_writable {
85 ($($t:ty),*) => {
86 $(
87 impl VarIntWritable for $t {
88 #[inline(always)]
89 fn is_zero(self) -> bool {
90 self == 0
91 }
92
93 #[inline(always)]
94 fn low_7_bits(self) -> u8 {
95 (self & 0x7F) as u8
96 }
97
98 #[inline(always)]
99 fn shr_7(&mut self) {
100 *self >>= 7;
101 }
102 }
103 )*
104 };
105}
106
107impl_varint_writable!(u8, u16, u32, u64, usize, u128);