#![warn(missing_docs)]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/")]
static OUT_OF_RANGE_MSG: &str = "Out of range";
static LEN_TOO_BIG_MSG: &str = "The length parameter is too big for a ";
type Result<T> = std::result::Result<T, String>;
pub trait TypeInfo {
fn type_of(&self) -> &'static str;
}
impl TypeInfo for u8 { fn type_of(&self) -> &'static str {"u8"} }
impl TypeInfo for u16 { fn type_of(&self) -> &'static str {"u16"} }
impl TypeInfo for u32 { fn type_of(&self) -> &'static str {"u32"} }
impl TypeInfo for u64 { fn type_of(&self) -> &'static str {"u64"} }
impl TypeInfo for i8 { fn type_of(&self) -> &'static str {"i8"} }
impl TypeInfo for i16 { fn type_of(&self) -> &'static str {"i16"} }
impl TypeInfo for i32 { fn type_of(&self) -> &'static str {"i32"} }
impl TypeInfo for i64 { fn type_of(&self) -> &'static str {"i64"} }
impl TypeInfo for f32 { fn type_of(&self) -> &'static str {"f32"} }
impl TypeInfo for f64 { fn type_of(&self) -> &'static str {"f64"} }
pub trait SignedInfo{
fn is_signed(&self) -> bool;
}
impl SignedInfo for u8 { fn is_signed(&self) -> bool { false } }
impl SignedInfo for u16 { fn is_signed(&self) -> bool { false } }
impl SignedInfo for u32 { fn is_signed(&self) -> bool { false } }
impl SignedInfo for u64 { fn is_signed(&self) -> bool { false } }
impl SignedInfo for i8 { fn is_signed(&self) -> bool { true } }
impl SignedInfo for i16 { fn is_signed(&self) -> bool { true } }
impl SignedInfo for i32 { fn is_signed(&self) -> bool { true } }
impl SignedInfo for i64 { fn is_signed(&self) -> bool { true } }
macro_rules! s {
( $x:expr ) => { String::from($x); };
}
macro_rules! check_max_bit_offset {
( $x:expr ) => {
if $x > ( std::mem::size_of::<Self>() * 8 - 1 ) as u32 {
return Err(s!(OUT_OF_RANGE_MSG));
}
}
}
macro_rules! check_range {
( $x:expr ) => {
if $x > std::mem::size_of::<Self>() * 8 {
return Err(s!(OUT_OF_RANGE_MSG));
}
}
}
pub fn n_required_bits_for_an_unsigned_int(num: u64) -> usize {
let i = num as f64;
let j = i.log2();
if j > 0_f64 {
j.floor() as usize + 1
}
else { 1 }
}
pub fn n_required_bits_for_a_signed_int(num: i64) -> usize {
let i = num as f64;
let j = i.abs().log2();
if j > 0_f64 {
j.ceil() as usize + 1
}
else { 1 }
}
pub trait ExtractBitsFromIntegralTypes {
fn get_u8(self, start: usize, length: usize) -> Result<(u8)>;
fn get_u16(self, start: usize, length: usize) -> Result<(u16)>;
fn get_u32(self, start: usize, length: usize) -> Result<(u32)>;
fn get_u64(self, start: usize, length: usize) -> Result<(u64)>;
fn get_i8(self, start: usize, length: usize) -> Result<(i8)>;
fn get_i16(self, start: usize, length: usize) -> Result<(i16)>;
fn get_i32(self, start: usize, length: usize) -> Result<(i32)>;
fn get_i64(self, start: usize, length: usize) -> Result<(i64)>;
}
impl ExtractBitsFromIntegralTypes for u8 {
fn get_u8(self, start: usize, length: usize) -> Result<(u8)> {
check_range!(start + length);
let mut copy = self;
copy <<= start;
copy >>= 8 - length;
Ok(copy)
}
fn get_i8(self, start: usize, length: usize) -> Result<(i8)> {
check_range!(start + length);
let mut copy = self as i8;
copy <<= start;
copy >>= 8 - length;
Ok(copy)
}
#[inline]
fn get_u16(self, start: usize, length: usize) -> Result<(u16)> {
Ok(self.get_u8(start, length)? as u16)
}
#[inline]
fn get_i16(self, start: usize, length: usize) -> Result<(i16)> {
Ok(self.get_i8(start, length)? as i16)
}
#[inline]
fn get_u32(self, start: usize, length: usize) -> Result<(u32)> {
Ok(self.get_u8(start, length)? as u32)
}
#[inline]
fn get_i32(self, start: usize, length: usize) -> Result<(i32)> {
Ok(self.get_i8(start, length)? as i32)
}
#[inline]
fn get_u64(self, start: usize, length: usize) -> Result<(u64)> {
Ok(self.get_u8(start, length)? as u64)
}
#[inline]
fn get_i64(self, start: usize, length: usize) -> Result<(i64)> {
Ok(self.get_i8(start, length)? as i64)
}
}
impl ExtractBitsFromIntegralTypes for i8 {
#[inline]
fn get_u8(self, start: usize, length: usize) -> Result<(u8)> {
(self as u8).get_u8(start, length)
}
#[inline]
fn get_i8(self, start: usize, length: usize) -> Result<(i8)> {
(self as u8).get_i8(start, length)
}
#[inline]
fn get_u16(self, start: usize, length: usize) -> Result<(u16)> {
(self as u8).get_u16(start, length)
}
#[inline]
fn get_i16(self, start: usize, length: usize) -> Result<(i16)> {
(self as u8).get_i16(start, length)
}
#[inline]
fn get_u32(self, start: usize, length: usize) -> Result<(u32)> {
(self as u8).get_u32(start, length)
}
#[inline]
fn get_i32(self, start: usize, length: usize) -> Result<(i32)> {
(self as u8).get_i32(start, length)
}
#[inline]
fn get_u64(self, start: usize, length: usize) -> Result<(u64)> {
(self as u8).get_u64(start, length)
}
#[inline]
fn get_i64(self, start: usize, length: usize) -> Result<(i64)> {
(self as u8).get_i64(start, length)
}
}
impl ExtractBitsFromIntegralTypes for u16 {
fn get_u8(self, start: usize, length: usize) -> Result<(u8)> {
if length > 8 {
return Err(s!(LEN_TOO_BIG_MSG) + "u8");
}
Ok(self.get_u16(start, length)? as u8)
}
fn get_i8(self, start: usize, length: usize) -> Result<(i8)> {
if length > 8 {
return Err(s!(LEN_TOO_BIG_MSG) + "i8");
}
Ok(self.get_i16(start, length)? as i8)
}
fn get_u16(self, start: usize, length: usize) -> Result<(u16)> {
check_range!(start + length);
let mut copy = self;
copy <<= start;
copy >>= 16 - length;
Ok(copy)
}
fn get_i16(self, start: usize, length: usize) -> Result<(i16)> {
check_range!(start + length);
let mut copy = self as i16;
copy <<= start;
copy >>= 16 - length;
Ok(copy)
}
#[inline]
fn get_u32(self, start: usize, length: usize) -> Result<(u32)> {
Ok(self.get_u16(start, length)? as u32)
}
#[inline]
fn get_i32(self, start: usize, length: usize) -> Result<(i32)> {
Ok(self.get_i16(start, length)? as i32)
}
#[inline]
fn get_u64(self, start: usize, length: usize) -> Result<(u64)> {
Ok(self.get_u16(start, length)? as u64)
}
#[inline]
fn get_i64(self, start: usize, length: usize) -> Result<(i64)> {
Ok(self.get_i16(start, length)? as i64)
}
}
impl ExtractBitsFromIntegralTypes for i16 {
#[inline]
fn get_u8(self, start: usize, length: usize) -> Result<(u8)> {
(self as u16).get_u8(start, length)
}
#[inline]
fn get_i8(self, start: usize, length: usize) -> Result<(i8)> {
(self as u16).get_i8(start, length)
}
#[inline]
fn get_u16(self, start: usize, length: usize) -> Result<(u16)> {
(self as u16).get_u16(start, length)
}
#[inline]
fn get_i16(self, start: usize, length: usize) -> Result<(i16)> {
(self as u16).get_i16(start, length)
}
#[inline]
fn get_u32(self, start: usize, length: usize) -> Result<(u32)> {
(self as u16).get_u32(start, length)
}
#[inline]
fn get_i32(self, start: usize, length: usize) -> Result<(i32)> {
(self as u16).get_i32(start, length)
}
#[inline]
fn get_u64(self, start: usize, length: usize) -> Result<(u64)> {
(self as u16).get_u64(start, length)
}
#[inline]
fn get_i64(self, start: usize, length: usize) -> Result<(i64)> {
(self as u16).get_i64(start, length)
}
}
impl ExtractBitsFromIntegralTypes for u32 {
fn get_u8(self, start: usize, length: usize) -> Result<(u8)> {
if length > 8 {
return Err(s!(LEN_TOO_BIG_MSG) + "u8");
}
Ok(self.get_u32(start, length)? as u8)
}
fn get_i8(self, start: usize, length: usize) -> Result<(i8)> {
if length > 8 {
return Err(s!(LEN_TOO_BIG_MSG) + "i8");
}
Ok(self.get_i32(start, length)? as i8)
}
fn get_u16(self, start: usize, length: usize) -> Result<(u16)> {
if length > 16 {
return Err(s!(LEN_TOO_BIG_MSG) + "u16");
}
Ok(self.get_u32(start, length)? as u16)
}
fn get_i16(self, start: usize, length: usize) -> Result<(i16)> {
if length > 16 {
return Err(s!(LEN_TOO_BIG_MSG) + "i16");
}
Ok(self.get_i32(start, length)? as i16)
}
fn get_u32(self, start: usize, length: usize) -> Result<(u32)> {
check_range!(start + length);
let mut copy = self;
copy <<= start;
copy >>= 32 - length;
Ok(copy)
}
fn get_i32(self, start: usize, length: usize) -> Result<(i32)> {
check_range!(start + length);
let mut copy = self as i32;
copy <<= start;
copy >>= 32 - length;
Ok(copy)
}
#[inline]
fn get_u64(self, start: usize, length: usize) -> Result<(u64)> {
Ok(self.get_u32(start, length)? as u64)
}
#[inline]
fn get_i64(self, start: usize, length: usize) -> Result<(i64)> {
Ok(self.get_i32(start, length)? as i64)
}
}
impl ExtractBitsFromIntegralTypes for i32 {
#[inline]
fn get_u8(self, start: usize, length: usize) -> Result<(u8)> {
(self as u32).get_u8(start, length)
}
#[inline]
fn get_i8(self, start: usize, length: usize) -> Result<(i8)> {
(self as u32).get_i8(start, length)
}
#[inline]
fn get_u16(self, start: usize, length: usize) -> Result<(u16)> {
(self as u32).get_u16(start, length)
}
#[inline]
fn get_i16(self, start: usize, length: usize) -> Result<(i16)> {
(self as u32).get_i16(start, length)
}
#[inline]
fn get_u32(self, start: usize, length: usize) -> Result<(u32)> {
(self as u32).get_u32(start, length)
}
#[inline]
fn get_i32(self, start: usize, length: usize) -> Result<(i32)> {
(self as u32).get_i32(start, length)
}
#[inline]
fn get_u64(self, start: usize, length: usize) -> Result<(u64)> {
(self as u32).get_u64(start, length)
}
#[inline]
fn get_i64(self, start: usize, length: usize) -> Result<(i64)> {
(self as u32).get_i64(start, length)
}
}
impl ExtractBitsFromIntegralTypes for u64 {
fn get_u8(self, start: usize, length: usize) -> Result<(u8)> {
if length > 8 {
return Err(s!(LEN_TOO_BIG_MSG) + "u8");
}
Ok(self.get_u64(start, length)? as u8)
}
fn get_i8(self, start: usize, length: usize) -> Result<(i8)> {
if length > 8 {
return Err(s!(LEN_TOO_BIG_MSG) + "i8");
}
Ok(self.get_i64(start, length)? as i8)
}
fn get_u16(self, start: usize, length: usize) -> Result<(u16)> {
if length > 16 {
return Err(s!(LEN_TOO_BIG_MSG) + "u16");
}
Ok(self.get_u64(start, length)? as u16)
}
fn get_i16(self, start: usize, length: usize) -> Result<(i16)> {
if length > 16 {
return Err(s!(LEN_TOO_BIG_MSG) + "i16");
}
Ok(self.get_i64(start, length)? as i16)
}
fn get_u32(self, start: usize, length: usize) -> Result<(u32)> {
if length > 32 {
return Err(s!(LEN_TOO_BIG_MSG) + "u32");
}
Ok(self.get_u64(start, length)? as u32)
}
fn get_i32(self, start: usize, length: usize) -> Result<(i32)> {
if length > 32 {
return Err(s!(LEN_TOO_BIG_MSG) + "i32");
}
Ok(self.get_i64(start, length)? as i32)
}
fn get_u64(self, start: usize, length: usize) -> Result<(u64)> {
check_range!(start + length);
let mut copy = self;
copy <<= start;
copy >>= 64 - length;
Ok(copy)
}
fn get_i64(self, start: usize, length: usize) -> Result<(i64)> {
check_range!(start + length);
let mut copy = self as i64;
copy <<= start;
copy >>= 64 - length;
Ok(copy)
}
}
impl ExtractBitsFromIntegralTypes for i64 {
#[inline]
fn get_u8(self, start: usize, length: usize) -> Result<(u8)> {
(self as u64).get_u8(start, length)
}
#[inline]
fn get_i8(self, start: usize, length: usize) -> Result<(i8)> {
(self as u64).get_i8(start, length)
}
#[inline]
fn get_u16(self, start: usize, length: usize) -> Result<(u16)> {
(self as u64).get_u16(start, length)
}
#[inline]
fn get_i16(self, start: usize, length: usize) -> Result<(i16)> {
(self as u64).get_i16(start, length)
}
#[inline]
fn get_u32(self, start: usize, length: usize) -> Result<(u32)> {
(self as u64).get_u32(start, length)
}
#[inline]
fn get_i32(self, start: usize, length: usize) -> Result<(i32)> {
(self as u64).get_i32(start, length)
}
#[inline]
fn get_u64(self, start: usize, length: usize) -> Result<(u64)> {
(self as u64).get_u64(start, length)
}
#[inline]
fn get_i64(self, start: usize, length: usize) -> Result<(i64)> {
(self as u64).get_i64(start, length)
}
}
pub trait ExtractBitsFromVecU8 {
fn get_u8(&self, byte_offset: usize, start: usize, length: usize) -> Result<(u8)>;
fn get_i8(&self, byte_offset: usize, start: usize, length: usize) -> Result<(i8)>;
fn get_u16(&self, byte_offset: usize, start: usize, length: usize) -> Result<(u16)>;
fn get_i16(&self, byte_offset: usize, start: usize, length: usize) -> Result<(i16)>;
fn get_u32(&self, byte_offset: usize, start: usize, length: usize) -> Result<(u32)>;
fn get_i32(&self, byte_offset: usize, start: usize, length: usize) -> Result<(i32)>;
}
impl ExtractBitsFromVecU8 for Vec<u8> {
fn get_u8(&self, byte_offset: usize, bit_offset: usize, length: usize) -> Result<(u8)> {
if length <= 8 {
if self.len() * 8 >= byte_offset * 8 + bit_offset + length { let mut byte_offset_copy = byte_offset;
let mut bit_offset_copy = bit_offset;
byte_offset_copy += bit_offset_copy / 8; bit_offset_copy -= (bit_offset_copy / 8) * 8;
if bit_offset_copy + length <= 8 {
let mut copy: u8 = self[byte_offset_copy];
copy = u8::from_be(copy);
copy <<= bit_offset_copy;
copy >>= 8 - length;
return Ok(copy);
} else { let copy1: u8 = self[byte_offset_copy];
let mut copy1_as_u16: u16 = copy1 as u16;
copy1_as_u16 <<= 8;
let copy2: u8 = self[byte_offset_copy + 1];
let mut result = copy1_as_u16 | (copy2 as u16);
result <<= bit_offset_copy;
result >>= 16 - length;
return Ok(result as u8);
}
} else {
return Err(s!(OUT_OF_RANGE_MSG))
}
} else {
return Err(s!(OUT_OF_RANGE_MSG))
}
}
fn get_i8(&self, byte_offset: usize, bit_offset: usize, length: usize) -> Result<(i8)> {
if length <= 8 {
if self.len() * 8 >= byte_offset * 8 + bit_offset + length { let mut byte_offset_copy = byte_offset;
let mut bit_offset_copy = bit_offset;
byte_offset_copy += bit_offset_copy / 8; bit_offset_copy -= (bit_offset_copy / 8) * 8;
if bit_offset_copy + length <= 8 {
let mut copy: i8 = self[byte_offset_copy] as i8;
copy = i8::from_be(copy);
copy <<= bit_offset_copy;
copy >>= 8 - length;
return Ok(copy);
} else { let copy1: i8 = self[byte_offset_copy] as i8;
let mut copy1_as_i16: i16 = copy1 as i16;
copy1_as_i16 <<= 8;
let copy2: i8 = self[byte_offset_copy + 1] as i8;
let mut result = copy1_as_i16 | (copy2 as i16);
result <<= bit_offset_copy;
result >>= 16 - length;
return Ok(result as i8);
}
} else {
return Err(s!(OUT_OF_RANGE_MSG))
}
} else {
return Err(s!(OUT_OF_RANGE_MSG))
}
}
fn get_u16(&self, byte_offset: usize, bit_offset: usize, length: usize) -> Result<(u16)> {
if length <= 16 {
if self.len() * 8 >= byte_offset * 8 + bit_offset + length { let mut byte_offset_copy = byte_offset;
let mut bit_offset_copy = bit_offset;
byte_offset_copy += bit_offset_copy / 8; bit_offset_copy -= (bit_offset_copy / 8) * 8;
if bit_offset_copy + length <= 8 {
let copy1 = self[byte_offset_copy] as i8;
let mut copy2 = copy1 as u16;
copy2 <<= 8 + bit_offset_copy;
copy2 >>= 16 - length;
return Ok(copy2);
} else if bit_offset_copy + length <= 16 {
let mut copy1 = self[byte_offset_copy] as u16;
copy1 <<= 8;
let copy2 = self[byte_offset_copy + 1] as u16;
let mut copy3 = copy1 | copy2;
copy3 <<= bit_offset_copy;
copy3 >>= 16 - length;
return Ok(copy3);
} else { let mut copy1 = self[byte_offset_copy] as u32;
copy1 <<= 16;
let mut copy2 = self[byte_offset_copy + 1] as u32;
copy2 <<= 8;
let copy3 = self[byte_offset_copy + 2] as u32;
let mut copy4 = copy1 | copy2 | copy3;
copy4 <<= bit_offset_copy + 8;
copy4 >>= 32 - length;
return Ok(copy4 as u16);
}
} else {
return Err(s!(OUT_OF_RANGE_MSG))
}
} else {
return Err(s!(OUT_OF_RANGE_MSG))
}
}
fn get_i16(&self, byte_offset: usize, bit_offset: usize, length: usize) -> Result<(i16)> {
if length <= 16 {
if self.len() * 8 >= byte_offset * 8 + bit_offset + length { let mut byte_offset_copy = byte_offset;
let mut bit_offset_copy = bit_offset;
byte_offset_copy += bit_offset_copy / 8; bit_offset_copy -= (bit_offset_copy / 8) * 8;
if bit_offset_copy + length <= 8 {
let copy1 = self[byte_offset_copy] as i8;
let mut copy2 = copy1 as i16;
copy2 <<= 8 + bit_offset_copy;
copy2 >>= 16 - length;
return Ok(copy2);
} else if bit_offset_copy + length <= 16 {
let mut copy1 = self[byte_offset_copy] as i16;
copy1 <<= 8;
let copy2 = self[byte_offset_copy + 1] as i16;
let mut copy3 = copy1 | copy2;
copy3 <<= bit_offset_copy;
copy3 >>= 16 - length;
return Ok(copy3);
} else { let mut copy1 = self[byte_offset_copy] as i32;
copy1 <<= 16;
let mut copy2 = self[byte_offset_copy + 1] as i32;
copy2 <<= 8;
let copy3 = self[byte_offset_copy + 2] as i32;
let mut copy4 = copy1 | copy2 | copy3;
copy4 <<= bit_offset_copy + 8;
copy4 >>= 32 - length;
return Ok(copy4 as i16);
}
} else {
return Err(s!(OUT_OF_RANGE_MSG))
}
} else {
return Err(s!(OUT_OF_RANGE_MSG))
}
}
fn get_u32(&self, byte_offset: usize, bit_offset: usize, length: usize) -> Result<(u32)> {
if length <= 32 {
if self.len() * 8 >= byte_offset * 8 + bit_offset + length { let mut byte_offset_copy = byte_offset;
let mut bit_offset_copy = bit_offset;
byte_offset_copy += bit_offset_copy / 8; bit_offset_copy -= (bit_offset_copy / 8) * 8;
if bit_offset_copy + length <= 8 {
let copy1 = self[byte_offset_copy] as u8;
let mut copy2 = copy1 as u32;
copy2 <<= 24 + bit_offset_copy;
copy2 >>= 32 - length;
return Ok(copy2);
} else if bit_offset_copy + length <= 16 {
let mut copy1 = self[byte_offset_copy] as u32;
copy1 <<= 8;
let copy2 = self[byte_offset_copy + 1] as u32;
let mut copy3 = copy1 | copy2;
copy3 <<= bit_offset_copy + 16;
copy3 >>= 32 - length;
return Ok(copy3);
} else if bit_offset_copy + length <= 24 {
let mut copy1 = self[byte_offset_copy] as u32;
copy1 <<= 16;
let mut copy2 = self[byte_offset_copy + 1] as u32;
copy2 <<= 8;
let copy3 = self[byte_offset_copy + 2] as u32;
let mut copy4 = copy1 | copy2 | copy3;
copy4 <<= bit_offset_copy + 8;
copy4 >>= 32 - length;
return Ok(copy4 as u32);
} else if bit_offset_copy + length <= 32 {
let mut copy1 = self[byte_offset_copy] as u32;
copy1 <<= 24;
let mut copy2 = self[byte_offset_copy + 1] as u32;
copy2 <<= 16;
let mut copy3 = self[byte_offset_copy + 2] as u32;
copy3 <<= 8;
let copy4 = self[byte_offset_copy + 3] as u32;
let mut copy5 = copy1 | copy2 | copy3 | copy4;
copy5 <<= bit_offset_copy;
copy5 >>= 32 - length;
return Ok(copy5 as u32);
} else {
let mut copy1 = self[byte_offset_copy] as u64;
copy1 <<= 32;
let mut copy2 = self[byte_offset_copy + 1] as u64;
copy2 <<= 24;
let mut copy3 = self[byte_offset_copy + 2] as u64;
copy3 <<= 16;
let mut copy4 = self[byte_offset_copy + 3] as u64;
copy4 <<= 8;
let copy5 = self[byte_offset_copy + 4] as u64;
let mut copy6 = copy1 | copy2 | copy3 | copy4 | copy5;
copy6 <<= 24 + bit_offset_copy;
copy6 >>= 64 - length;
return Ok(copy6 as u32);
}
} else {
return Err(s!(OUT_OF_RANGE_MSG))
}
} else {
return Err(s!(OUT_OF_RANGE_MSG))
}
}
fn get_i32(&self, byte_offset: usize, bit_offset: usize, length: usize) -> Result<(i32)> {
if length <= 32 {
if self.len() * 8 >= byte_offset * 8 + bit_offset + length { let mut byte_offset_copy = byte_offset;
let mut bit_offset_copy = bit_offset;
byte_offset_copy += bit_offset_copy / 8; bit_offset_copy -= (bit_offset_copy / 8) * 8;
if bit_offset_copy + length <= 8 {
let copy1 = self[byte_offset_copy] as i8;
let mut copy2 = copy1 as i32;
copy2 <<= 24 + bit_offset_copy;
copy2 >>= 32 - length;
return Ok(copy2);
} else if bit_offset_copy + length <= 16 {
let mut copy1 = self[byte_offset_copy] as i32;
copy1 <<= 8;
let copy2 = self[byte_offset_copy + 1] as i32;
let mut copy3 = copy1 | copy2;
copy3 <<= bit_offset_copy + 16;
copy3 >>= 32 - length;
return Ok(copy3);
} else if bit_offset_copy + length <= 24 {
let mut copy1 = self[byte_offset_copy] as i32;
copy1 <<= 16;
let mut copy2 = self[byte_offset_copy + 1] as i32;
copy2 <<= 8;
let copy3 = self[byte_offset_copy + 2] as i32;
let mut copy4 = copy1 | copy2 | copy3;
copy4 <<= bit_offset_copy + 8;
copy4 >>= 32 - length;
return Ok(copy4 as i32);
} else if bit_offset_copy + length <= 32 {
let mut copy1 = self[byte_offset_copy] as i32;
copy1 <<= 24;
let mut copy2 = self[byte_offset_copy + 1] as i32;
copy2 <<= 16;
let mut copy3 = self[byte_offset_copy + 2] as i32;
copy3 <<= 8;
let copy4 = self[byte_offset_copy + 3] as i32;
let mut copy5 = copy1 | copy2 | copy3 | copy4;
copy5 <<= bit_offset_copy;
copy5 >>= 32 - length;
return Ok(copy5 as i32);
} else {
let mut copy1 = self[byte_offset_copy] as i64;
copy1 <<= 32;
let mut copy2 = self[byte_offset_copy + 1] as i64;
copy2 <<= 24;
let mut copy3 = self[byte_offset_copy + 2] as i64;
copy3 <<= 16;
let mut copy4 = self[byte_offset_copy + 3] as i64;
copy4 <<= 8;
let copy5 = self[byte_offset_copy + 4] as i64;
let mut copy6 = copy1 | copy2 | copy3 | copy4 | copy5;
copy6 <<= 24 + bit_offset_copy;
copy6 >>= 64 - length;
return Ok(copy6 as i32);
}
} else {
return Err(s!(OUT_OF_RANGE_MSG))
}
} else {
return Err(s!(OUT_OF_RANGE_MSG))
}
}
}
pub trait SingleBits {
fn set_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized;
fn get_bit(self, bit_offset: u32) -> Result<(bool)>;
fn clear_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized;
}
impl SingleBits for u8 {
fn set_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let mut a : u8 = 0b1000_0000;
a >>= bit_offset;
let mut copy = self;
copy |= a;
Ok(copy)
}
fn get_bit(self, bit_offset: u32) -> Result<(bool)> {
check_max_bit_offset!(bit_offset);
let mut a : u8 = 0b1000_0000;
a >>= bit_offset;
let mut copy = self;
copy = copy & a;
if copy > 0 {
Ok(true)
} else {
Ok(false)
}
}
fn clear_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let a : u8 = 0b0111_1111;
let a = a.rotate_right(bit_offset);
let mut copy = self;
copy &= a;
Ok(copy)
}
}
impl SingleBits for i8 {
fn set_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let mut a : u8 = 0b1000_0000;
a >>= bit_offset;
let mut copy = self as u8;
copy |= a;
Ok(copy as i8)
}
fn get_bit(self, bit_offset: u32) -> Result<(bool)> {
check_max_bit_offset!(bit_offset);
let mut a : u8 = 0b1000_0000;
a >>= bit_offset;
let mut copy = self as u8;
copy = copy & a;
if copy > 0 {
Ok(true)
} else {
Ok(false)
}
}
fn clear_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let a : u8 = 0b0111_1111;
let a = a.rotate_right(bit_offset);
let mut copy = self as u8;
copy &= a;
Ok(copy as i8)
}
}
impl SingleBits for u16 {
fn set_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let mut a : u16 = 0b1000_0000_0000_0000;
a >>= bit_offset;
let mut copy = self;
copy |= a;
Ok(copy)
}
fn get_bit(self, bit_offset: u32) -> Result<(bool)> {
check_max_bit_offset!(bit_offset);
let mut a : u16 = 0b1000_0000_0000_0000;
a >>= bit_offset;
let mut copy = self;
copy = copy & a;
if copy > 0 {
Ok(true)
} else {
Ok(false)
}
}
fn clear_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let a : u16 = 0b0111_1111_1111_1111;
let a = a.rotate_right(bit_offset);
let mut copy = self;
copy &= a;
Ok(copy)
}
}
impl SingleBits for i16 {
fn set_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let mut a : u16 = 0b1000_0000_0000_0000;
a >>= bit_offset;
let mut copy = self as u16;
copy |= a;
Ok(copy as i16)
}
fn get_bit(self, bit_offset: u32) -> Result<(bool)> {
check_max_bit_offset!(bit_offset);
let mut a : u16 = 0b1000_0000_0000_0000;
a >>= bit_offset;
let mut copy = self as u16;
copy = copy & a;
if copy > 0 {
Ok(true)
} else {
Ok(false)
}
}
fn clear_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let a : u16 = 0b0111_1111_1111_1111;
let a = a.rotate_right(bit_offset);
let mut copy = self as u16;
copy &= a;
Ok(copy as i16)
}
}
impl SingleBits for u32 {
fn set_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let mut a : u32 = 0b1000_0000_0000_0000_0000_0000_0000_0000;
a >>= bit_offset;
let mut copy = self;
copy |= a;
Ok(copy)
}
fn get_bit(self, bit_offset: u32) -> Result<(bool)> {
check_max_bit_offset!(bit_offset);
let mut a : u32 = 0b1000_0000_0000_0000_0000_0000_0000_0000;
a >>= bit_offset;
let mut copy = self;
copy = copy & a;
if copy > 0 {
Ok(true)
} else {
Ok(false)
}
}
fn clear_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let a : u32 = 0b0111_1111_1111_1111_1111_1111_1111_1111;
let a = a.rotate_right(bit_offset);
let mut copy = self;
copy &= a;
Ok(copy)
}
}
impl SingleBits for i32 {
fn set_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let mut a : u32 = 0b1000_0000_0000_0000_0000_0000_0000_0000;
a >>= bit_offset;
let mut copy = self as u32;
copy |= a;
Ok(copy as i32)
}
fn get_bit(self, bit_offset: u32) -> Result<(bool)> {
check_max_bit_offset!(bit_offset);
let mut a : u32 = 0b1000_0000_0000_0000_0000_0000_0000_0000;
a >>= bit_offset;
let mut copy = self as u32;
copy = copy & a;
if copy > 0 {
Ok(true)
} else {
Ok(false)
}
}
fn clear_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let a : u32 = 0b0111_1111_1111_1111_1111_1111_1111_1111;
let a = a.rotate_right(bit_offset);
let mut copy = self as u32;
copy &= a;
Ok(copy as i32)
}
}
impl SingleBits for u64 {
fn set_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let mut a : u64 = 0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000;
a >>= bit_offset;
let mut copy = self;
copy |= a;
Ok(copy)
}
fn get_bit(self, bit_offset: u32) -> Result<(bool)> {
check_max_bit_offset!(bit_offset);
let mut a : u64 = 0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000;
a >>= bit_offset;
let mut copy = self;
copy = copy & a;
if copy > 0 {
Ok(true)
} else {
Ok(false)
}
}
fn clear_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let a : u64 = 0b0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111;
let a = a.rotate_right(bit_offset);
let mut copy = self;
copy &= a;
Ok(copy)
}
}
impl SingleBits for i64 {
fn set_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let mut a : u64 = 0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000;
a >>= bit_offset;
let mut copy = self as u64;
copy |= a;
Ok(copy as i64)
}
fn get_bit(self, bit_offset: u32) -> Result<(bool)> {
check_max_bit_offset!(bit_offset);
let mut a : u64 = 0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000;
a >>= bit_offset;
let mut copy = self as u64;
copy = copy & a;
if copy > 0 {
Ok(true)
} else {
Ok(false)
}
}
fn clear_bit(self, bit_offset: u32) -> Result<(Self)> where Self: std::marker::Sized {
check_max_bit_offset!(bit_offset);
let a : u64 = 0b0111_1111_1111_1111_1111_1111_1111_1111;
let a = a.rotate_right(bit_offset);
let mut copy = self as u64;
copy &= a;
Ok(copy as i64)
}
}
pub trait InsertBitsIntoIntegralTypes {
fn set_u8(self, start: usize, length: usize, value: u8) -> Result<(Self)> where Self: std::marker::Sized;
fn set_i8(self, start: usize, length: usize, value: i8) -> Result<(Self)> where Self: std::marker::Sized;
fn set_u16(self, start: usize, length: usize, value: u16) -> Result<(Self)> where Self: std::marker::Sized;
fn set_i16(self, start: usize, length: usize, value: i16) -> Result<(Self)> where Self: std::marker::Sized;
fn set_u32(self, start: usize, length: usize, value: u32) -> Result<(Self)> where Self: std::marker::Sized;
fn set_i32(self, start: usize, length: usize, value: i32) -> Result<(Self)> where Self: std::marker::Sized;
fn set_u64(self, start: usize, length: usize, value: u64) -> Result<(Self)> where Self: std::marker::Sized;
fn set_i64(self, start: usize, length: usize, value: i64) -> Result<(Self)> where Self: std::marker::Sized;
}
macro_rules! def_set_fn {
($n:tt, $t:ty) => (
fn $n(self, start: usize, length: usize, value: $t) -> Result<(Self)> {
let mut value_copy = value;
let mut result = self;
if length > std::mem::size_of::<Self>() * 8 {
return Err(s!(LEN_TOO_BIG_MSG) + TypeInfo::type_of(&self));
}
check_range!(start + length);
if value.is_signed() {
let n = n_required_bits_for_a_signed_int(value as i64);
if n > length {
return Err(format!("Cannot insert {} as a {} bit signed integer variable, since it requires at least {} bits.",
&value.to_string(), &length.to_string(), &n.to_string()))
}
} else {
let n = n_required_bits_for_an_unsigned_int(value as u64);
if n > length {
return Err(format!("Cannot insert {} as a {} bit unsigned integer variable, since it requires at least {} bits.",
&value.to_string(), &length.to_string(), &n.to_string()))
}
}
value_copy <<= std::mem::size_of_val(&value) as u8 * 8 - (start + length) as u8;
for i in start .. start + length {
if value_copy.get_bit(i as u32)? {
result = result.set_bit(i as u32)?;
} else {
result = result.clear_bit(i as u32)?;
}
}
Ok(result)
}
)
}
impl InsertBitsIntoIntegralTypes for u8 {
def_set_fn!(set_u8, u8);
def_set_fn!(set_u16, u16);
def_set_fn!(set_u32, u32);
def_set_fn!(set_u64, u64);
def_set_fn!(set_i8, i8);
def_set_fn!(set_i16, i16);
def_set_fn!(set_i32, i32);
def_set_fn!(set_i64, i64);
}
impl InsertBitsIntoIntegralTypes for u16 {
def_set_fn!(set_u8, u8);
def_set_fn!(set_u16, u16);
def_set_fn!(set_u32, u32);
def_set_fn!(set_u64, u64);
def_set_fn!(set_i8, i8);
def_set_fn!(set_i16, i16);
def_set_fn!(set_i32, i32);
def_set_fn!(set_i64, i64);
}
impl InsertBitsIntoIntegralTypes for u32 {
def_set_fn!(set_u8, u8);
def_set_fn!(set_u16, u16);
def_set_fn!(set_u32, u32);
def_set_fn!(set_u64, u64);
def_set_fn!(set_i8, i8);
def_set_fn!(set_i16, i16);
def_set_fn!(set_i32, i32);
def_set_fn!(set_i64, i64);
}
impl InsertBitsIntoIntegralTypes for u64 {
def_set_fn!(set_u8, u8);
def_set_fn!(set_u16, u16);
def_set_fn!(set_u32, u32);
def_set_fn!(set_u64, u64);
def_set_fn!(set_i8, i8);
def_set_fn!(set_i16, i16);
def_set_fn!(set_i32, i32);
def_set_fn!(set_i64, i64);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn range_checks_for_integrals() {
let a: u8 = 0x05;
match a.get_u8(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u16(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u32(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u64(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i8(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i16(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i32(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i64(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
let a: u16 = 0x05AA;
match a.get_u8(20, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u16(0, 17) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u16(20, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u8(2, 12) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "u8"),
}
match a.get_i8(2, 12) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "i8"),
}
let a: u32 = 0x05AAAAAA;
match a.get_u8(20, 9) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "u8"),
}
match a.get_u16(0, 18) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "u16"),
}
match a.get_u32(20, 30) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u64(0, 70) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i8(20, 9) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "i8"),
}
match a.get_i16(0, 18) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "i16"),
}
match a.get_i32(20, 30) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i64(0, 70) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
let a: u64 = 0x05AAAAAA00000000;
match a.get_u8(20, 9) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "u8"),
}
match a.get_u16(0, 18) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "u16"),
}
match a.get_u32(0, 33) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "u32"),
}
match a.get_u64(0, 70) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u64(62, 4) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i8(20, 9) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "i8"),
}
match a.get_i16(0, 18) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "i16"),
}
match a.get_i32(0, 33) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "i32"),
}
match a.get_i64(0, 70) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i64(62, 4) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
let a: i8 = 0x05;
match a.get_u8(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u16(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u32(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u64(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i8(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i16(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i32(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i64(5, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
let a: i16 = 0x05AA;
match a.get_u8(20, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u16(0, 17) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u16(20, 7) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u8(2, 12) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "u8"),
}
match a.get_i8(2, 12) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "i8"),
}
let a: i32 = 0x05AAAAAA;
match a.get_u8(20, 9) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "u8"),
}
match a.get_u16(0, 18) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "u16"),
}
match a.get_u32(20, 30) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u64(0, 70) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i8(20, 9) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "i8"),
}
match a.get_i16(0, 18) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "i16"),
}
match a.get_i32(20, 30) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i64(0, 70) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
let a: i64 = 0x05AAAAAA00000000;
match a.get_u8(20, 9) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "u8"),
}
match a.get_u16(0, 18) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "u16"),
}
match a.get_u32(0, 33) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "u32"),
}
match a.get_u64(0, 70) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_u64(62, 4) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i8(20, 9) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "i8"),
}
match a.get_i16(0, 18) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "i16"),
}
match a.get_i32(0, 33) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, s!(LEN_TOO_BIG_MSG) + "i32"),
}
match a.get_i64(0, 70) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match a.get_i64(62, 4) {
Ok(_) => panic!("Missed the range check"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
}
#[test]
fn range_checks_for_vec_u8() {
let v: Vec<u8> = vec!{ 0x48, 0x61, 0x6C, 0x6C, 0x6F };
match v.get_u8(5, 2, 3) {
Ok(_) => panic!("The range check failed to detect invalid byte offset"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match v.get_u8(1, 5, 12) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match v.get_u8(4, 7, 5) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match v.get_u16(1, 5, 17) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
match v.get_u16(4, 7, 10) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, OUT_OF_RANGE_MSG),
}
}
#[test]
fn source_must_not_change() {
let a: u8 = 0x05;
let _b = a.get_u16(3, 4).unwrap();
assert_eq!(a, 0x05, "The source has changed!");
let a: u16 = 0x05AA;
let _b = a.get_u16(5, 3).unwrap();
assert_eq!(a, 0x05AA, "The source has changed!");
let a: u32 = 0x05AA0000;
let _b = a.get_u16(5, 3).unwrap();
assert_eq!(a, 0x05AA0000, "The source has changed!");
let a: u64 = 0x05AA00000000;
let _b = a.get_u16(5, 3).unwrap();
assert_eq!(a, 0x05AA00000000, "The source has changed!");
let a: i8 = 0x05;
let _b = a.get_i16(3, 4).unwrap();
assert_eq!(a, 0x05, "The source has changed!");
let a: i16 = 0x05AA;
let _b = a.get_i16(5, 3).unwrap();
assert_eq!(a, 0x05AA, "The source has changed!");
let a: i32 = 0x05AA0000;
let _b = a.get_i16(5, 3).unwrap();
assert_eq!(a, 0x05AA0000, "The source has changed!");
let a: i64 = 0x05AA00000000;
let _b = a.get_i16(5, 3).unwrap();
assert_eq!(a, 0x05AA00000000, "The source has changed!");
}
macro_rules! get_5_3 {
( $a:ident, $x:ident, $y:expr ) => {
let b = $a.$x(5, 3).unwrap(); assert_eq!(b, $y);
};
}
#[test]
fn correct_results() {
let a: u8 = 0b0000_0101;
get_5_3!(a, get_u8, 5);
get_5_3!(a, get_i8, -3);
get_5_3!(a, get_u16, 5);
get_5_3!(a, get_i16, -3);
get_5_3!(a, get_u32, 5);
get_5_3!(a, get_i32, -3);
get_5_3!(a, get_u64, 5);
get_5_3!(a, get_i64, -3);
let a: i8 = 0b0000_0101;
get_5_3!(a, get_u8, 5);
get_5_3!(a, get_i8, -3);
get_5_3!(a, get_u16, 5);
get_5_3!(a, get_i16, -3);
get_5_3!(a, get_u32, 5);
get_5_3!(a, get_i32, -3);
get_5_3!(a, get_u64, 5);
get_5_3!(a, get_i64, -3);
let a: u16 = 0b0000_0101_1010_1010;
get_5_3!(a, get_u8, 5);
get_5_3!(a, get_i8, -3);
get_5_3!(a, get_u16, 5);
get_5_3!(a, get_i16, -3);
get_5_3!(a, get_u32, 5);
get_5_3!(a, get_i32, -3);
get_5_3!(a, get_u64, 5);
get_5_3!(a, get_i64, -3);
let b = a.get_u8(12, 3).unwrap(); assert_eq!(b, 5);
let b = a.get_i8(12, 3).unwrap(); assert_eq!(b, -3);
let a: i16 = 0b0000_0101_1010_1010;
get_5_3!(a, get_u8, 5);
get_5_3!(a, get_i8, -3);
get_5_3!(a, get_u16, 5);
get_5_3!(a, get_i16, -3);
get_5_3!(a, get_u32, 5);
get_5_3!(a, get_i32, -3);
get_5_3!(a, get_u64, 5);
get_5_3!(a, get_i64, -3);
let b = a.get_u8(12, 3).unwrap(); assert_eq!(b, 5);
let b = a.get_i8(12, 3).unwrap(); assert_eq!(b, -3);
let a: u32 = 0b0000_0101_1010_1010_1010_1010_1010_1010;
get_5_3!(a, get_u8, 5);
get_5_3!(a, get_i8, -3);
get_5_3!(a, get_u16, 5);
get_5_3!(a, get_i16, -3);
get_5_3!(a, get_u32, 5);
get_5_3!(a, get_i32, -3);
get_5_3!(a, get_u64, 5);
get_5_3!(a, get_i64, -3);
let b = a.get_u8(12, 3).unwrap(); assert_eq!(b, 5);
let b = a.get_i8(12, 3).unwrap(); assert_eq!(b, -3);
let a: i32 = 0b0000_0101_1010_1010_1010_1010_1010_1010;
get_5_3!(a, get_u8, 5);
get_5_3!(a, get_i8, -3);
get_5_3!(a, get_u16, 5);
get_5_3!(a, get_i16, -3);
get_5_3!(a, get_u32, 5);
get_5_3!(a, get_i32, -3);
get_5_3!(a, get_u64, 5);
get_5_3!(a, get_i64, -3);
let b = a.get_u8(12, 3).unwrap(); assert_eq!(b, 5);
let b = a.get_i8(12, 3).unwrap(); assert_eq!(b, -3);
let a: u64 = 0b0000_0101_1010_1010_1010_1010_1010_1010_0000_0101_1010_1010_1010_1010_1010_1010;
get_5_3!(a, get_u8, 5);
get_5_3!(a, get_i8, -3);
get_5_3!(a, get_u16, 5);
get_5_3!(a, get_i16, -3);
get_5_3!(a, get_u32, 5);
get_5_3!(a, get_i32, -3);
get_5_3!(a, get_u64, 5);
get_5_3!(a, get_i64, -3);
let b = a.get_i8(60, 3).unwrap(); assert_eq!(b, -3);
let b = a.get_u8(60, 3).unwrap(); assert_eq!(b, 5);
let a: i64 = 0b0000_0101_1010_1010_1010_1010_1010_1010_0000_0101_1010_1010_1010_1010_1010_1010;
get_5_3!(a, get_u8, 5);
get_5_3!(a, get_i8, -3);
get_5_3!(a, get_u16, 5);
get_5_3!(a, get_i16, -3);
get_5_3!(a, get_u32, 5);
get_5_3!(a, get_i32, -3);
get_5_3!(a, get_u64, 5);
get_5_3!(a, get_i64, -3);
let b = a.get_i8(60, 3).unwrap(); assert_eq!(b, -3);
let b = a.get_u8(60, 3).unwrap(); assert_eq!(b, 5);
}
#[test]
fn extract_from_vector() {
let v: Vec<u8> = vec!{ 0x48, 0x61, 0x6C, 0x6C, 0x6F };
let bar = v.get_u8(1, 5, 3); assert_eq!(bar.unwrap(), 1);
let bar = v.get_u8(1, 1, 4); assert_eq!(bar.unwrap(), 12);
let bar = v.get_u8(1, 7, 5); assert_eq!(bar.unwrap(), 22);
let bar = v.get_u8(0, 36, 3); assert_eq!(bar.unwrap(), 7);
let bar = v.get_u8(0, 30, 3); assert_eq!(bar.unwrap(), 0);
let bar = v.get_i8(1, 5, 3); assert_eq!(bar.unwrap(), 1);
let bar = v.get_i8(1, 2, 3); assert_eq!(bar.unwrap(), -4);
let bar = v.get_i8(1, 7, 5); assert_eq!(bar.unwrap(), -10);
let bar = v.get_i8(0, 36, 3); assert_eq!(bar.unwrap(), -1);
let bar = v.get_u16(1, 7, 3); assert_eq!(bar.unwrap(), 5);
let bar = v.get_u16(4, 3, 5); assert_eq!(bar.unwrap(), 15);
let bar = v.get_u16(1, 7, 10); assert_eq!(bar.unwrap(), 728);
let bar = v.get_u16(0, 36, 3); assert_eq!(bar.unwrap(), 7);
let bar = v.get_i16(1, 7, 3); assert_eq!(bar.unwrap(), -3);
let bar = v.get_i16(4, 3, 5); assert_eq!(bar.unwrap(), 15);
let bar = v.get_i16(1, 7, 10); assert_eq!(bar.unwrap(), -296);
let bar = v.get_i16(0, 36, 3); assert_eq!(bar.unwrap(), -1);
let v: Vec<u8> = vec!{ 0x48, 0x61, 0x6C, 0x6C, 0x6F, 0x2C, 0x20, 0x57, 0x65, 0x6C, 0x74, 0x21 };
let bar = v.get_u32(0, 0, 3); assert_eq!(bar.unwrap(), 2);
let bar = v.get_u32(1, 7, 3); assert_eq!(bar.unwrap(), 5);
let bar = v.get_u32(4, 3, 5); assert_eq!(bar.unwrap(), 15);
let bar = v.get_u32(5, 3, 16); assert_eq!(bar.unwrap(), 24834);
let bar = v.get_u32(5, 3, 28); assert_eq!(bar.unwrap(), 101723058);
let bar = v.get_u32(5, 3, 32); assert_eq!(bar.unwrap(), 1627568939);
let bar = v.get_u32(1, 7, 26); assert_eq!(bar.unwrap(), 47765726);
let bar = v.get_u32(0, 36, 3); assert_eq!(bar.unwrap(), 7);
let bar = v.get_i32(0, 0, 3); assert_eq!(bar.unwrap(), 2);
let bar = v.get_i32(1, 7, 3); assert_eq!(bar.unwrap(), -3);
let bar = v.get_i32(4, 3, 5); assert_eq!(bar.unwrap(), 15);
let bar = v.get_i32(5, 3, 16); assert_eq!(bar.unwrap(), 24834);
let bar = v.get_i32(5, 3, 28); assert_eq!(bar.unwrap(), 101723058);
let bar = v.get_i32(5, 3, 32); assert_eq!(bar.unwrap(), 1627568939);
let bar = v.get_i32(1, 7, 26); assert_eq!(bar.unwrap(), -19343138);
let bar = v.get_i32(0, 36, 3); assert_eq!(bar.unwrap(), -1);
}
#[test]
#[should_panic]
fn panics_as_expected() {
panic!("So far, nothing should panic!");
}
#[test]
fn single_bits() {
let a: u8 = 0b0000_0101;
assert_eq!(a.get_bit(0).unwrap(), false);
assert_eq!(a.get_bit(5).unwrap(), true);
let b = 0;
assert_eq!(a.set_bit(b).unwrap(), 133);
assert_eq!(a.clear_bit(b).unwrap(), 5);
let b = 1;
assert_eq!(a.set_bit(b).unwrap(), 69);
assert_eq!(a.clear_bit(b).unwrap(), 5);
let a: u16 = 0b0000_0000_0000_0101;
assert_eq!(a.get_bit(0).unwrap(), false);
assert_eq!(a.get_bit(13).unwrap(), true);
let b = 0;
assert_eq!(a.set_bit(b).unwrap(), 32773);
assert_eq!(a.clear_bit(b).unwrap(), 5);
let b = 1;
assert_eq!(a.set_bit(b).unwrap(), 16389);
assert_eq!(a.clear_bit(b).unwrap(), 5);
let a: u32 = 0b0000_0000_0000_0000_0000_0000_0000_0101;
assert_eq!(a.get_bit(0).unwrap(), false);
assert_eq!(a.get_bit(29).unwrap(), true);
let b = 0;
assert_eq!(a.set_bit(b).unwrap(), 2_147_483_653 );
assert_eq!(a.clear_bit(b).unwrap(), 5);
let b = 1;
assert_eq!(a.set_bit(b).unwrap(), 1_073_741_829);
assert_eq!(a.clear_bit(b).unwrap(), 5);
let a: u64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0101;
assert_eq!(a.get_bit(0).unwrap(), false);
assert_eq!(a.get_bit(61).unwrap(), true);
let b = 0;
assert_eq!(a.set_bit(b).unwrap(), 0x80_00_00_00_00_00_00_05);
assert_eq!(a.clear_bit(b).unwrap(), 5);
let b = 1;
assert_eq!(a.set_bit(b).unwrap(), 0x40_00_00_00_00_00_00_05);
assert_eq!(a.clear_bit(b).unwrap(), 5);
let a: i8 = 0b0000_0101;
assert_eq!(a.get_bit(0).unwrap(), false);
assert_eq!(a.get_bit(5).unwrap(), true);
let b = 0;
assert_eq!(a.set_bit(b).unwrap(), -123);
assert_eq!(a.clear_bit(b).unwrap(), 5);
let b = 1;
assert_eq!(a.set_bit(b).unwrap(), 69);
assert_eq!(a.clear_bit(b).unwrap(), 5);
let a: i16 = 0b0000_0000_0000_0101;
assert_eq!(a.get_bit(0).unwrap(), false);
assert_eq!(a.get_bit(13).unwrap(), true);
let b = 0;
assert_eq!(a.set_bit(b).unwrap(), -32763);
assert_eq!(a.clear_bit(b).unwrap(), 5);
let b = 1;
assert_eq!(a.set_bit(b).unwrap(), 16389);
assert_eq!(a.clear_bit(b).unwrap(), 5);
let a: i32 = 0b0000_0000_0000_0000_0000_0000_0000_0101;
assert_eq!(a.get_bit(0).unwrap(), false);
assert_eq!(a.get_bit(29).unwrap(), true);
let b = 0;
assert_eq!(a.set_bit(b).unwrap(), -2_147_483_643 );
assert_eq!(a.clear_bit(b).unwrap(), 5);
let b = 1;
assert_eq!(a.set_bit(b).unwrap(), 1_073_741_829);
assert_eq!(a.clear_bit(b).unwrap(), 5);
let a: i64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0101;
assert_eq!(a.get_bit(0).unwrap(), false);
assert_eq!(a.get_bit(61).unwrap(), true);
let b = 0;
assert_eq!(a.set_bit(b).unwrap(), -9_223_372_036_854_775_803);
assert_eq!(a.clear_bit(b).unwrap(), 5);
let b = 1;
assert_eq!(a.set_bit(b).unwrap(), 4_611_686_018_427_387_909);
assert_eq!(a.clear_bit(b).unwrap(), 5);
}
#[test]
fn inserting_8_bit_vars_into_u8() {
let a : u8 = 0;
let b : u8 = 3;
assert_eq!(a.set_u8(1, 2, b).unwrap(), 0b0110_0000);
let a : u8 = 0b0110_0011;
let b : u8 = 0b0000_0010;
assert_eq!(a.set_u8(5, 2, b).unwrap(), 0b0110_0101);
match a.set_u8(5, 9, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u8")),
}
match a.set_u8(5, 8, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let b = 5;
match a.set_u8(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Cannot insert 5 as a 2 bit unsigned integer variable, since it requires at least 3 bits.")),
}
let a : u8 = 0b0110_0011;
let b : i8 = 0b0000_0010;
assert_eq!(a.set_i8(5, 2, b).unwrap(), 0b0110_0101);
let b : i8 = -2;
assert_eq!( 0b1111_1110 as u8 as i8, b);
assert_eq!(a.set_i8(5, 2, b).unwrap(), 0b0110_0101);
match a.set_i8(5, 9, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u8")),
}
match a.set_i8(5, 8, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let b = -5;
match a.set_i8(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Cannot insert -5 as a 2 bit signed integer variable, since it requires at least 4 bits.")),
}
}
#[test]
fn inserting_8_bit_vars_into_u16() {
let a : u16 = 0;
let b : u8 = 3;
assert_eq!(a.set_u8(1, 2, b).unwrap(), 0b0110_0000_0000_0000);
let a : u16 = 0b0110_0011_0000_0000;
let b : u8 = 0b0000_0010;
assert_eq!(a.set_u8(5, 2, b).unwrap(), 0b0110_0101_0000_0000);
match a.set_u8(5, 18, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u16")),
}
match a.set_u8(5, 15, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let b = 5;
match a.set_u8(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Cannot insert 5 as a 2 bit unsigned integer variable, since it requires at least 3 bits.")),
}
let a : u16 = 0b0110_0011_0000_0110;
let b : i8 = 0b0000_0010;
assert_eq!(a.set_i8(5, 2, b).unwrap(), 0b0110_0101_0000_0110);
let b : i8 = -2;
assert_eq!( 0b1111_1110 as u8 as i8, b);
assert_eq!(a.set_i8(5, 2, b).unwrap(), 0b0110_0101_0000_0110);
match a.set_i8(5, 18, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u16")),
}
match a.set_i8(5, 15, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let b = -5;
match a.set_i8(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Cannot insert -5 as a 2 bit signed integer variable, since it requires at least 4 bits.")),
}
}
#[test]
fn inserting_8_bit_vars_into_u32() {
let a : u32 = 0;
let b : u8 = 3;
assert_eq!(a.set_u8(1, 2, b).unwrap(), 0b0110_0000_0000_0000_0000_0000_0000_0000);
let a : u32 = 0b0110_0011_0000_0000_0000_0000_0000_0000;
let b : u8 = 0b0000_0010;
assert_eq!(a.set_u8(5, 2, b).unwrap(), 0b0110_0101_0000_0000_0000_0000_0000_0000);
match a.set_u8(5, 40, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u32")),
}
match a.set_u8(5, 30, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let b = 5;
match a.set_u8(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Cannot insert 5 as a 2 bit unsigned integer variable, since it requires at least 3 bits.")),
}
let a : u32 = 0b0110_0011_0000_0110_0110_0011_0000_0110;
let b : i8 = 0b0000_0010;
assert_eq!(a.set_i8(5, 2, b).unwrap(), 0b0110_0101_0000_0110_0110_0011_0000_0110);
let b : i8 = -2;
assert_eq!( 0b1111_1110 as u8 as i8, b);
assert_eq!(a.set_i8(5, 2, b).unwrap(), 0b0110_0101_0000_0110_0110_0011_0000_0110);
match a.set_i8(5, 40, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u32")),
}
match a.set_i8(5, 30, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let b = -5;
match a.set_i8(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Cannot insert -5 as a 2 bit signed integer variable, since it requires at least 4 bits.")),
}
}
#[test]
fn inserting_8_bit_vars_into_u64() {
let a : u64 = 0;
let b : u8 = 3;
assert_eq!(a.set_u8(1, 2, b).unwrap(), 0b0110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
let a : u64 = 0b0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000;
let b : u8 = 0b0000_0010;
assert_eq!(a.set_u8(5, 2, b).unwrap(), 0b0110_0101_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
match a.set_u8(5, 80, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u64")),
}
match a.set_u8(5, 60, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let b = 5;
match a.set_u8(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Cannot insert 5 as a 2 bit unsigned integer variable, since it requires at least 3 bits.")),
}
let a : u64 = 0b0110_0011_0000_0110_0110_0011_0000_0110_0000_0000_0000_0000_0000_0000_0000_0000;
let b : i8 = 0b0000_0010;
assert_eq!(a.set_i8(5, 2, b).unwrap(), 0b0110_0101_0000_0110_0110_0011_0000_0110_0000_0000_0000_0000_0000_0000_0000_0000);
let b : i8 = -2;
assert_eq!( 0b1111_1110 as u8 as i8, b);
assert_eq!(a.set_i8(5, 2, b).unwrap(), 0b0110_0101_0000_0110_0110_0011_0000_0110_0000_0000_0000_0000_0000_0000_0000_0000);
match a.set_i8(5, 80, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u64")),
}
match a.set_i8(5, 60, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let b = -5;
match a.set_i8(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Cannot insert -5 as a 2 bit signed integer variable, since it requires at least 4 bits.")),
}
}
#[test]
fn inserting_16_bit_vars_into_u8() {
let a : u8 = 0;
let b : u16 = 3;
assert_eq!(a.set_u16(1, 2, b).unwrap(), 0b0110_0000);
let a : u8 = 0b0110_0011;
let b : u16 = 0b0000_0000_0000_0010;
assert_eq!(a.set_u16(5, 2, b).unwrap(), 0b0110_0101);
match a.set_u16(5, 9, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u8")),
}
match a.set_u16(5, 8, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let a : u8 = 0b0110_0011;
let b : i16 = 0b0000_0000_0000_0010;
assert_eq!(a.set_i16(5, 2, b).unwrap(), 0b0110_0101);
let b : i16 = -2;
assert_eq!( 0b1111_1111_1111_1110 as u16 as i16, b);
assert_eq!(a.set_i16(5, 2, b).unwrap(), 0b0110_0101);
match a.set_i16(5, 9, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u8")),
}
match a.set_i16(5, 8, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
}
#[test]
fn inserting_16_bit_vars_into_u16() {
let a : u16 = 0;
let b : u16 = 3;
assert_eq!(a.set_u16(1, 2, b).unwrap(), 0b0110_0000_0000_0000);
let a : u16 = 0b0110_0011_0000_1110;
let b : u16 = 0b0000_0000_0000_0010;
assert_eq!(a.set_u16(5, 2, b).unwrap(), 0b0110_0101_0000_1110);
match a.set_u16(5, 18, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u16")),
}
match a.set_u16(5, 15, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let a : u16 = 0b0110_0011_0000_1110;
let b : i16 = 0b0000_0000_0000_0010;
assert_eq!(a.set_i16(5, 2, b).unwrap(), 0b0110_0101_0000_1110);
let b : i16 = -2;
assert_eq!( 0b1111_1111_1111_1110 as u16 as i16, b);
assert_eq!(a.set_i16(5, 2, b).unwrap(), 0b0110_0101_0000_1110);
match a.set_i16(5, 18, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u16")),
}
match a.set_i16(5, 15, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
}
#[test]
fn inserting_16_bit_vars_into_u32() {
let a : u32 = 0;
let b : u16 = 3;
assert_eq!(a.set_u16(1, 2, b).unwrap(), 0b0110_0000_0000_0000_0000_0000_0000_0000);
let a : u32 = 0b0110_0011_0000_1110_0000_0000_0000_0000;
let b : u16 = 0b0000_0000_0000_0010;
assert_eq!(a.set_u16(5, 2, b).unwrap(), 0b0110_0101_0000_1110_0000_0000_0000_0000);
match a.set_u16(5, 40, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u32")),
}
match a.set_u16(5, 30, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let a : u32 = 0b0110_0011_0000_1110_0000_0000_0000_0000;
let b : i16 = 0b0000_0000_0000_0010;
assert_eq!(a.set_i16(5, 2, b).unwrap(), 0b0110_0101_0000_1110_0000_0000_0000_0000);
let b : i16 = -2;
assert_eq!( 0b1111_1111_1111_1110 as u16 as i16, b);
assert_eq!(a.set_i16(5, 2, b).unwrap(), 0b0110_0101_0000_1110_0000_0000_0000_0000);
match a.set_i16(5, 40, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u32")),
}
match a.set_i16(5, 30, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
}
#[test]
fn inserting_16_bit_vars_into_u64() {
let a : u64 = 0;
let b : u16 = 3;
assert_eq!(a.set_u16(1, 2, b).unwrap(), 0b0110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
let a : u64 = 0b0110_0011_0000_1110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000;
let b : u16 = 0b0000_0000_0000_0010;
assert_eq!(a.set_u16(5, 2, b).unwrap(), 0b0110_0101_0000_1110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
match a.set_u16(5, 80, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u64")),
}
match a.set_u16(5, 60, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let a : u64 = 0b0110_0011_0000_1110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000;
let b : i16 = 0b0000_0000_0000_0010;
assert_eq!(a.set_i16(5, 2, b).unwrap(), 0b0110_0101_0000_1110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
let b : i16 = -2;
assert_eq!( 0b1111_1111_1111_1110 as u16 as i16, b);
assert_eq!(a.set_i16(5, 2, b).unwrap(), 0b0110_0101_0000_1110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
match a.set_i16(5, 80, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u64")),
}
match a.set_i16(5, 60, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
}
#[test]
fn inserting_32_bit_vars_into_u8() {
let a : u8 = 0;
let b : u32 = 3;
assert_eq!(a.set_u32(1, 2, b).unwrap(), 0b0110_0000);
let a : u8 = 0b0110_0011;
let b : u32 = 0b0000_0000_0000_0010;
assert_eq!(a.set_u32(5, 2, b).unwrap(), 0b0110_0101);
match a.set_u32(5, 9, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u8")),
}
match a.set_u32(5, 8, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let a : u8 = 0b0110_0011;
let b : i32 = 0b0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set_i32(5, 2, b).unwrap(), 0b0110_0101);
let b : i32 = -2;
assert_eq!( 0b1111_1111_1111_1111_1111_1111_1111_1110 as u32 as i32, b);
assert_eq!(a.set_i32(5, 2, b).unwrap(), 0b0110_0101);
match a.set_i32(5, 9, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u8")),
}
match a.set_i32(5, 8, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
}
#[test]
fn inserting_32_bit_vars_into_u16() {
let a : u16 = 0;
let b : u32 = 3;
assert_eq!(a.set_u32(1, 2, b).unwrap(), 0b0110_0000_0000_0000);
let a : u16 = 0b0000_0000_0110_0011;
let b : u32 = 2;
assert_eq!(a.set_u32(5, 2, b).unwrap(), 0b0000_0100_0110_0011);
match a.set_u32(5, 18, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u16")),
}
match a.set_u32(5, 15, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let a : u16 = 0b0000_0000_0110_0011;
let b : i32 = 2;
assert_eq!(a.set_i32(5, 2, b).unwrap(), 0b0000_0100_0110_0011);
let b : i32 = -2;
assert_eq!( 0b1111_1111_1111_1111_1111_1111_1111_1110 as u32 as i32, b);
assert_eq!(a.set_i32(5, 2, b).unwrap(), 0b0000_0100_0110_0011);
match a.set_i32(5, 18, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u16")),
}
match a.set_i32(5, 15, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
}
#[test]
fn inserting_32_bit_vars_into_u32() {
let a : u32 = 0;
let b : u32 = 3;
assert_eq!(a.set_u32(1, 2, b).unwrap(), 0b0110_0000_0000_0000_0000_0000_0000_0000);
let a : u32 = 0b0000_0000_0110_0011_0000_0000_0000_0000;
let b : u32 = 2;
assert_eq!(a.set_u32(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000);
match a.set_u32(5, 40, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u32")),
}
match a.set_u32(5, 30, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let a : u32 = 0b0000_0000_0110_0011_0000_0000_0000_0000;
let b : i32 = 2;
assert_eq!(a.set_i32(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000);
let b : i32 = -2;
assert_eq!( 0b1111_1111_1111_1111_1111_1111_1111_1110 as u32 as i32, b);
assert_eq!(a.set_i32(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000);
match a.set_i32(5, 40, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u32")),
}
match a.set_i32(5, 30, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
}
#[test]
fn inserting_32_bit_vars_into_u64() {
let a : u64 = 0;
let b : u32 = 3;
assert_eq!(a.set_u32(1, 2, b).unwrap(), 0b0110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
let a : u64 = 0b0000_0000_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000;
let b : u32 = 2;
assert_eq!(a.set_u32(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
match a.set_u32(5, 80, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u64")),
}
match a.set_u32(5, 60, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let a : u64 = 0b0000_0000_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000;
let b : i32 = 2;
assert_eq!(a.set_i32(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
let b : i32 = -2;
assert_eq!( 0b1111_1111_1111_1111_1111_1111_1111_1110 as u32 as i32, b);
assert_eq!(a.set_i32(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
match a.set_i32(5, 80, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u64")),
}
match a.set_i32(5, 60, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
}
#[test]
fn inserting_64_bit_vars_into_u8() {
let a : u8 = 0;
let b : u64 = 3;
assert_eq!(a.set_u64(1, 2, b).unwrap(), 0b0110_0000);
let a : u8 = 0b0110_0011;
let b : u64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set_u64(5, 2, b).unwrap(), 0b0110_0101);
match a.set_u64(5, 9, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u8")),
}
match a.set_u64(5, 8, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let a : u8 = 0b0110_0011;
let b : i64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set_i64(5, 2, b).unwrap(), 0b0110_0101);
let b : i64 = -2;
assert_eq!( 0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1110 as u64 as i64, b);
assert_eq!(a.set_i64(5, 2, b).unwrap(), 0b0110_0101);
match a.set_i64(5, 9, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u8")),
}
match a.set_i64(5, 8, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
}
#[test]
fn inserting_64_bit_vars_into_u16() {
let a : u16 = 0;
let b : u64 = 3;
assert_eq!(a.set_u64(1, 2, b).unwrap(), 0b0110_0000_0000_0000);
let a : u16 = 0b0000_0000_0110_0011;
let b : u64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set_u64(5, 2, b).unwrap(), 0b0000_0100_0110_0011);
match a.set_u64(5, 18, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u16")),
}
match a.set_u64(5, 15, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let a : u16 = 0b0000_0000_0110_0011;
let b : i64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set_i64(5, 2, b).unwrap(), 0b0000_0100_0110_0011);
let b : i64 = -2;
assert_eq!( 0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1110 as u64 as i64, b);
assert_eq!(a.set_i64(5, 2, b).unwrap(), 0b0000_0100_0110_0011);
match a.set_i64(5, 18, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u16")),
}
match a.set_i64(5, 15, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
}
#[test]
fn inserting_64_bit_vars_into_u32() {
let a : u32 = 0;
let b : u64 = 3;
assert_eq!(a.set_u64(1, 2, b).unwrap(), 0b0110_0000_0000_0000_0000_0000_0000_0000);
let a : u32 = 0b0000_0000_0110_0011_0000_0000_0000_0000;
let b : u64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set_u64(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000);
match a.set_u64(5, 40, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u32")),
}
match a.set_u64(5, 30, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let a : u32 = 0b0000_0000_0110_0011_0000_0000_0000_0000;
let b : i64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set_i64(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000);
let b : i64 = -2;
assert_eq!( 0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1110 as u64 as i64, b);
assert_eq!(a.set_i64(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000);
match a.set_i64(5, 40, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u32")),
}
match a.set_i64(5, 30, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
}
#[test]
fn inserting_64_bit_vars_into_u64() {
let a : u64 = 0;
let b : u64 = 3;
assert_eq!(a.set_u64(1, 2, b).unwrap(), 0b0110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
let a : u64 = 0b0000_0000_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000;
let b : u64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set_u64(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
match a.set_u64(5, 80, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u64")),
}
match a.set_u64(5, 60, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
let a : u64 = 0b0000_0000_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000;
let b : i64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set_i64(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
let b : i64 = -2;
assert_eq!( 0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1110 as u64 as i64, b);
assert_eq!(a.set_i64(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
match a.set_i64(5, 80, b) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!(s!(LEN_TOO_BIG_MSG) + "u64")),
}
match a.set_i64(5, 60, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
}
#[test]
fn test_number_of_bits_required_for_an_unsinged_integer() {
assert_eq!(n_required_bits_for_an_unsigned_int(0), 1);
assert_eq!(n_required_bits_for_an_unsigned_int(1), 1);
assert_eq!(n_required_bits_for_an_unsigned_int(2), 2);
assert_eq!(n_required_bits_for_an_unsigned_int(3), 2);
assert_eq!(n_required_bits_for_an_unsigned_int(4), 3);
assert_eq!(n_required_bits_for_an_unsigned_int(5), 3);
assert_eq!(n_required_bits_for_an_unsigned_int(6), 3);
assert_eq!(n_required_bits_for_an_unsigned_int(7), 3);
assert_eq!(n_required_bits_for_an_unsigned_int(8), 4);
assert_eq!(n_required_bits_for_an_unsigned_int(255), 8);
assert_eq!(n_required_bits_for_an_unsigned_int(256), 9);
}
#[test]
fn test_number_of_bits_required_for_a_singed_integer() {
assert_eq!(n_required_bits_for_a_signed_int(0), 1);
assert_eq!(n_required_bits_for_a_signed_int(-1), 1);
assert_eq!(n_required_bits_for_a_signed_int(-2), 2);
assert_eq!(n_required_bits_for_a_signed_int(-3), 3);
assert_eq!(n_required_bits_for_a_signed_int(-4), 3);
assert_eq!(n_required_bits_for_a_signed_int(-5), 4);
assert_eq!(n_required_bits_for_a_signed_int(-6), 4);
assert_eq!(n_required_bits_for_a_signed_int(-7), 4);
assert_eq!(n_required_bits_for_a_signed_int(-8), 4);
assert_eq!(n_required_bits_for_a_signed_int(-63), 7);
assert_eq!(n_required_bits_for_a_signed_int(-64), 7);
assert_eq!(n_required_bits_for_a_signed_int(-65), 8);
assert_eq!(n_required_bits_for_a_signed_int(-127), 8);
assert_eq!(n_required_bits_for_a_signed_int(-128), 8);
assert_eq!(n_required_bits_for_a_signed_int(-129), 9);
}
}