#[cfg(test)]
use proptest::{num::i32, num::i64, prelude::*};
pub fn encode_i32(v: i32) -> u64 {
((v << 1) ^ (v >> 31)) as u64
}
pub fn decode_u32(v: u64) -> i32 {
(v as u32 >> 1) as i32 ^ -(v as i32 & 1)
}
pub fn encode_i64(v: i64) -> u64 {
((v << 1) ^ (v >> 63)) as u64
}
pub fn decode_u64(v: u64) -> i64 {
((v >> 1) ^ (-((v & 1) as i64)) as u64) as i64
}
#[cfg(test)]
#[allow(clippy::panic)]
mod tests {
use super::*;
#[allow(overflowing_literals)]
#[test]
fn test_expected_values() {
assert_eq!(0, encode_i32(0));
assert_eq!(1, encode_i32(-1));
assert_eq!(2, encode_i32(1));
assert_eq!(3, encode_i32(-2));
assert_eq!(0x7FFF_FFFE, encode_i32(0x3FFF_FFFF));
assert_eq!(0x7FFF_FFFF, encode_i32(0xC000_0000));
assert_eq!(0xFFFF_FFFE, encode_i32(0x7FFF_FFFF) as i32);
assert_eq!(0xFFFF_FFFF, encode_i32(0x8000_0000) as i32);
assert_eq!(0, encode_i64(0));
assert_eq!(1, encode_i64(-1));
assert_eq!(2, encode_i64(1));
assert_eq!(3, encode_i64(-2));
assert_eq!(0x0000_0000_7FFF_FFFE, encode_i64(0x0000_0000_3FFF_FFFF));
assert_eq!(0x0000_0000_7FFF_FFFF, encode_i64(0xFFFF_FFFF_C000_0000));
assert_eq!(0x0000_0000_FFFF_FFFE, encode_i64(0x0000_0000_7FFF_FFFF));
assert_eq!(0x0000_0000_FFFF_FFFF, encode_i64(0xFFFF_FFFF_8000_0000));
assert_eq!(0xFFFF_FFFF_FFFF_FFFE, encode_i64(0x7FFF_FFFF_FFFF_FFFF));
assert_eq!(0xFFFF_FFFF_FFFF_FFFF, encode_i64(0x8000_0000_0000_0000));
}
proptest! {
#[test]
fn encode_i32_roundtrip(i in i32::ANY) {
let dec = decode_u32(encode_i32(i));
prop_assert_eq![i, dec];
}
#[test]
fn encode_i64_roundtrip(i in i64::ANY) {
let dec = decode_u64(encode_i64(i));
prop_assert_eq![i, dec];
}
}
}