pub trait SerializableInt: ::num_traits::ToBytes + ::num_traits::Zero {
fn min_bit_count(&self) -> u32;
fn shr_to_u32(&self, shift_amount: u8) -> u32;
fn bit_size() -> u32;
fn from_u8(value: u8) -> Self;
}
macro_rules! serializable_unsigned_int_impl {
($($t:ty)*) => ($(
impl SerializableInt for $t {
fn min_bit_count(&self) -> u32 {
<$t>::BITS - self.leading_zeros()
}
fn shr_to_u32(&self, shift_amount: u8) -> u32 {
self.checked_shr(shift_amount as u32).unwrap_or(0) as u32
}
fn bit_size() -> u32 {
<$t>::BITS
}
fn from_u8(value: u8) -> Self {
value as $t
}
}
)*);
}
macro_rules! serializable_signed_int_impl {
($($t:ty)*) => ($(
impl SerializableInt for $t {
fn min_bit_count(&self) -> u32 {
if self < &mut <$t as num_traits::Zero>::zero() {
<$t>::BITS - self.leading_ones() + 1
} else {
<$t>::BITS - self.leading_zeros() + 1
}
}
fn shr_to_u32(&self, shift_amount: u8) -> u32 {
self.checked_shr(shift_amount as u32).unwrap_or(0) as u32
}
fn bit_size() -> u32 {
<$t>::BITS
}
fn from_u8(value: u8) -> Self {
value as $t
}
}
)*)
}
serializable_unsigned_int_impl!(u16 u32 u64 u128 usize);
serializable_signed_int_impl!(i16 i32 i64 i128 isize);
impl SerializableInt for u8 {
fn min_bit_count(&self) -> u32 {
u8::BITS - self.leading_zeros()
}
fn shr_to_u32(&self, shift_amount: u8) -> u32 {
(*self as u32).checked_shr(shift_amount as u32).unwrap_or(0)
}
fn bit_size() -> u32 {
u8::BITS
}
fn from_u8(value: u8) -> Self {
value
}
}
impl SerializableInt for i8 {
fn min_bit_count(&self) -> u32 {
if *self < 0 {
i8::BITS - self.leading_ones() + 1
} else {
i8::BITS - self.leading_zeros() + 1
}
}
fn shr_to_u32(&self, shift_amount: u8) -> u32 {
(*self as u32).checked_shr(shift_amount as u32).unwrap_or(0)
}
fn bit_size() -> u32 {
i8::BITS
}
fn from_u8(value: u8) -> Self {
value as i8
}
}
#[cfg(test)]
mod tests {
use super::SerializableInt;
#[test]
fn min_bit_count() {
for i in u8::MIN..u8::MAX {
assert_eq!(
i.min_bit_count(),
8 - i.leading_zeros(),
"Minimum bit count for u8 '{}' is not correct",
i
);
}
assert_eq!(
(0_i8).min_bit_count(),
1,
"Minimum bit count for i8 '0' is not correct"
);
assert_eq!(
(-2_i8).min_bit_count(),
2,
"Minimum bit count for i8 '-2' is not correct"
);
assert_eq!(
(2_i8).min_bit_count(),
3,
"Minimum bit count for i8 '2' is not correct"
);
assert_eq!(
(i8::MIN).min_bit_count(),
i8::BITS,
"Minimum bit count for i8 '{}' is not correct",
i8::MIN
);
assert_eq!(
(i8::MAX).min_bit_count(),
i8::BITS,
"Minimum bit count for i8 '{}' is not correct",
i8::MAX
);
assert_eq!(
(0_i16).min_bit_count(),
1,
"Minimum bit count for i16 '0' is not correct"
);
assert_eq!(
(-2_i16).min_bit_count(),
2,
"Minimum bit count for i16 '-2' is not correct"
);
assert_eq!(
(2_i16).min_bit_count(),
3,
"Minimum bit count for i16 '2' is not correct"
);
assert_eq!(
(i16::MIN).min_bit_count(),
i16::BITS,
"Minimum bit count for i16 '{}' is not correct",
i16::MIN
);
assert_eq!(
(i16::MAX).min_bit_count(),
i16::BITS,
"Minimum bit count for i16 '{}' is not correct",
i16::MAX
);
assert_eq!(
(0_i32).min_bit_count(),
1,
"Minimum bit count for i32 '0' is not correct"
);
assert_eq!(
(-2_i32).min_bit_count(),
2,
"Minimum bit count for i32 '-2' is not correct"
);
assert_eq!(
(2_i32).min_bit_count(),
3,
"Minimum bit count for i32 '2' is not correct"
);
assert_eq!(
(i32::MIN).min_bit_count(),
i32::BITS,
"Minimum bit count for i32 '{}' is not correct",
i32::MIN
);
assert_eq!(
(i32::MAX).min_bit_count(),
i32::BITS,
"Minimum bit count for i32 '{}' is not correct",
i32::MAX
);
assert_eq!(
(0_i64).min_bit_count(),
1,
"Minimum bit count for i64 '0' is not correct"
);
assert_eq!(
(-2_i64).min_bit_count(),
2,
"Minimum bit count for i64 '-2' is not correct"
);
assert_eq!(
(2_i64).min_bit_count(),
3,
"Minimum bit count for i64 '2' is not correct"
);
assert_eq!(
(i64::MIN).min_bit_count(),
i64::BITS,
"Minimum bit count for i64 '{}' is not correct",
i64::MIN
);
assert_eq!(
(i64::MAX).min_bit_count(),
i64::BITS,
"Minimum bit count for i64 '{}' is not correct",
i64::MAX
);
assert_eq!(
(0_i128).min_bit_count(),
1,
"Minimum bit count for i128 '0' is not correct"
);
assert_eq!(
(-2_i128).min_bit_count(),
2,
"Minimum bit count for i128 '-2' is not correct"
);
assert_eq!(
(2_i128).min_bit_count(),
3,
"Minimum bit count for i128 '2' is not correct"
);
assert_eq!(
(i128::MIN).min_bit_count(),
i128::BITS,
"Minimum bit count for i128 '{}' is not correct",
i128::MIN
);
assert_eq!(
(i128::MAX).min_bit_count(),
i128::BITS,
"Minimum bit count for i128 '{}' is not correct",
i128::MAX
);
assert_eq!(
(0_isize).min_bit_count(),
1,
"Minimum bit count for isize '0' is not correct"
);
assert_eq!(
(-2_isize).min_bit_count(),
2,
"Minimum bit count for isize '-2' is not correct"
);
assert_eq!(
(2_isize).min_bit_count(),
3,
"Minimum bit count for isize '2' is not correct"
);
assert_eq!(
(isize::MIN).min_bit_count(),
isize::BITS,
"Minimum bit count for isize '{}' is not correct",
isize::MIN
);
assert_eq!(
(isize::MAX).min_bit_count(),
isize::BITS,
"Minimum bit count for isize '{}' is not correct",
isize::MAX
);
assert_eq!(
(0_u8).min_bit_count(),
0,
"Minimum bit count for u8 '0' is not correct"
);
assert_eq!(
(2_u8).min_bit_count(),
2,
"Minimum bit count for u8 '2' is not correct"
);
assert_eq!(
(u8::MAX).min_bit_count(),
u8::BITS,
"Minimum bit count for u8 '{}' is not correct",
u8::MAX
);
assert_eq!(
(0_u16).min_bit_count(),
0,
"Minimum bit count for u16 '0' is not correct"
);
assert_eq!(
(2_u16).min_bit_count(),
2,
"Minimum bit count for u16 '2' is not correct"
);
assert_eq!(
(u16::MAX).min_bit_count(),
u16::BITS,
"Minimum bit count for u16 '{}' is not correct",
u16::MAX
);
assert_eq!(
(0_u32).min_bit_count(),
0,
"Minimum bit count for u32 '0' is not correct"
);
assert_eq!(
(2_u32).min_bit_count(),
2,
"Minimum bit count for u32 '2' is not correct"
);
assert_eq!(
(u32::MAX).min_bit_count(),
u32::BITS,
"Minimum bit count for u32 '{}' is not correct",
u32::MAX
);
assert_eq!(
(0_u64).min_bit_count(),
0,
"Minimum bit count for u64 '0' is not correct"
);
assert_eq!(
(2_u64).min_bit_count(),
2,
"Minimum bit count for u64 '2' is not correct"
);
assert_eq!(
(u64::MAX).min_bit_count(),
u64::BITS,
"Minimum bit count for u64 '{}' is not correct",
u64::MAX
);
assert_eq!(
(0_u128).min_bit_count(),
0,
"Minimum bit count for u128 '0' is not correct"
);
assert_eq!(
(2_u128).min_bit_count(),
2,
"Minimum bit count for u128 '2' is not correct"
);
assert_eq!(
(u128::MAX).min_bit_count(),
u128::BITS,
"Minimum bit count for u128 '{}' is not correct",
u128::MAX
);
assert_eq!(
(0_usize).min_bit_count(),
0,
"Minimum bit count for usize '0' is not correct"
);
assert_eq!(
(2_usize).min_bit_count(),
2,
"Minimum bit count for usize '2' is not correct"
);
assert_eq!(
(usize::MAX).min_bit_count(),
usize::BITS,
"Minimum bit count for usize '{}' is not correct",
usize::MAX
);
}
}