#![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/")]
extern crate num;
static OUT_OF_RANGE_MSG: &str = "Out of range";
static LEN_TOO_BIG_MSG: &str = "The length parameter is too big for a ";
static LEN_ZERO: &str = "The length parameter must not be zero";
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>() as u32 * 8 - 1 ) as u32 {
return Err(s!(OUT_OF_RANGE_MSG));
}
}
}
macro_rules! check_range {
( $bit_offset:expr, $length:expr ) => {
if $length == 0 {
return Err(s!(LEN_ZERO));
}
if $bit_offset + $length > std::mem::size_of::<Self>() as u32 * 8 {
return Err(s!(OUT_OF_RANGE_MSG));
}
}
}
pub fn n_required_bits_for_an_unsigned_int(num: u64) -> u32 {
let i = num as f64;
let j = i.log2();
if j > 0_f64 {
j.floor() as u32 + 1
}
else { 1 }
}
pub fn n_required_bits_for_a_signed_int(num: i64) -> u32 {
let i = num as f64;
let j = i.abs().log2();
if j > 0_f64 {
j.ceil() as u32 + 1
}
else { 1 }
}
pub trait ExtractBitsFromIntegralTypes {
fn get_u8(self, bit_offset: u32, length: u32) -> Result<u8>;
fn get_u16(self, bit_offset: u32, length: u32) -> Result<u16>;
fn get_u32(self, bit_offset: u32, length: u32) -> Result<u32>;
fn get_u64(self, bit_offset: u32, length: u32) -> Result<u64>;
fn get_i8(self, bit_offset: u32, length: u32) -> Result<i8>;
fn get_i16(self, bit_offset: u32, length: u32) -> Result<i16>;
fn get_i32(self, bit_offset: u32, length: u32) -> Result<i32>;
fn get_i64(self, bit_offset: u32, length: u32) -> Result<i64>;
}
impl ExtractBitsFromIntegralTypes for u8 {
fn get_u8(self, bit_offset: u32, length: u32) -> Result<u8> {
check_range!(bit_offset, length);
let mut copy = self;
copy <<= bit_offset;
copy >>= 8 - length;
Ok(copy)
}
fn get_i8(self, bit_offset: u32, length: u32) -> Result<i8> {
check_range!(bit_offset, length);
let mut copy = self as i8;
copy <<= bit_offset;
copy >>= 8 - length;
Ok(copy)
}
#[inline]
fn get_u16(self, bit_offset: u32, length: u32) -> Result<u16> {
Ok(self.get_u8 (bit_offset, length)? as u16)
}
#[inline]
fn get_i16(self, bit_offset: u32, length: u32) -> Result<i16> {
Ok(self.get_i8 (bit_offset, length)? as i16)
}
#[inline]
fn get_u32(self, bit_offset: u32, length: u32) -> Result<u32> {
Ok(self.get_u8 (bit_offset, length)? as u32)
}
#[inline]
fn get_i32(self, bit_offset: u32, length: u32) -> Result<i32> {
Ok(self.get_i8 (bit_offset, length)? as i32)
}
#[inline]
fn get_u64(self, bit_offset: u32, length: u32) -> Result<u64> {
Ok(self.get_u8 (bit_offset, length)? as u64)
}
#[inline]
fn get_i64(self, bit_offset: u32, length: u32) -> Result<i64> {
Ok(self.get_i8 (bit_offset, length)? as i64)
}
}
impl ExtractBitsFromIntegralTypes for i8 {
#[inline]
fn get_u8(self, bit_offset: u32, length: u32) -> Result<u8> {
(self as u8).get_u8 (bit_offset, length)
}
#[inline]
fn get_i8(self, bit_offset: u32, length: u32) -> Result<i8> {
(self as u8).get_i8 (bit_offset, length)
}
#[inline]
fn get_u16(self, bit_offset: u32, length: u32) -> Result<u16> {
(self as u8).get_u16 (bit_offset, length)
}
#[inline]
fn get_i16(self, bit_offset: u32, length: u32) -> Result<i16> {
(self as u8).get_i16 (bit_offset, length)
}
#[inline]
fn get_u32(self, bit_offset: u32, length: u32) -> Result<u32> {
(self as u8).get_u32 (bit_offset, length)
}
#[inline]
fn get_i32(self, bit_offset: u32, length: u32) -> Result<i32> {
(self as u8).get_i32 (bit_offset, length)
}
#[inline]
fn get_u64(self, bit_offset: u32, length: u32) -> Result<u64> {
(self as u8).get_u64 (bit_offset, length)
}
#[inline]
fn get_i64(self, bit_offset: u32, length: u32) -> Result<i64> {
(self as u8).get_i64 (bit_offset, length)
}
}
impl ExtractBitsFromIntegralTypes for u16 {
fn get_u8(self, bit_offset: u32, length: u32) -> Result<u8> {
if length > 8 {
return Err(s!(LEN_TOO_BIG_MSG) + "u8");
}
Ok(self.get_u16 (bit_offset, length)? as u8)
}
fn get_i8(self, bit_offset: u32, length: u32) -> Result<i8> {
if length > 8 {
return Err(s!(LEN_TOO_BIG_MSG) + "i8");
}
Ok(self.get_i16 (bit_offset, length)? as i8)
}
fn get_u16(self, bit_offset: u32, length: u32) -> Result<u16> {
check_range!(bit_offset, length);
let mut copy = self;
copy <<= bit_offset;
copy >>= 16 - length;
Ok(copy)
}
fn get_i16(self, bit_offset: u32, length: u32) -> Result<i16> {
check_range!(bit_offset, length);
let mut copy = self as i16;
copy <<= bit_offset;
copy >>= 16 - length;
Ok(copy)
}
#[inline]
fn get_u32(self, bit_offset: u32, length: u32) -> Result<u32> {
Ok(self.get_u16 (bit_offset, length)? as u32)
}
#[inline]
fn get_i32(self, bit_offset: u32, length: u32) -> Result<i32> {
Ok(self.get_i16 (bit_offset, length)? as i32)
}
#[inline]
fn get_u64(self, bit_offset: u32, length: u32) -> Result<u64> {
Ok(self.get_u16 (bit_offset, length)? as u64)
}
#[inline]
fn get_i64(self, bit_offset: u32, length: u32) -> Result<i64> {
Ok(self.get_i16 (bit_offset, length)? as i64)
}
}
impl ExtractBitsFromIntegralTypes for i16 {
#[inline]
fn get_u8(self, bit_offset: u32, length: u32) -> Result<u8> {
(self as u16).get_u8 (bit_offset, length)
}
#[inline]
fn get_i8(self, bit_offset: u32, length: u32) -> Result<i8> {
(self as u16).get_i8 (bit_offset, length)
}
#[inline]
fn get_u16(self, bit_offset: u32, length: u32) -> Result<u16> {
(self as u16).get_u16 (bit_offset, length)
}
#[inline]
fn get_i16(self, bit_offset: u32, length: u32) -> Result<i16> {
(self as u16).get_i16 (bit_offset, length)
}
#[inline]
fn get_u32(self, bit_offset: u32, length: u32) -> Result<u32> {
(self as u16).get_u32 (bit_offset, length)
}
#[inline]
fn get_i32(self, bit_offset: u32, length: u32) -> Result<i32> {
(self as u16).get_i32 (bit_offset, length)
}
#[inline]
fn get_u64(self, bit_offset: u32, length: u32) -> Result<u64> {
(self as u16).get_u64 (bit_offset, length)
}
#[inline]
fn get_i64(self, bit_offset: u32, length: u32) -> Result<i64> {
(self as u16).get_i64 (bit_offset, length)
}
}
impl ExtractBitsFromIntegralTypes for u32 {
fn get_u8(self, bit_offset: u32, length: u32) -> Result<u8> {
if length > 8 {
return Err(s!(LEN_TOO_BIG_MSG) + "u8");
}
Ok(self.get_u32 (bit_offset, length)? as u8)
}
fn get_i8(self, bit_offset: u32, length: u32) -> Result<i8> {
if length > 8 {
return Err(s!(LEN_TOO_BIG_MSG) + "i8");
}
Ok(self.get_i32 (bit_offset, length)? as i8)
}
fn get_u16(self, bit_offset: u32, length: u32) -> Result<u16> {
if length > 16 {
return Err(s!(LEN_TOO_BIG_MSG) + "u16");
}
Ok(self.get_u32 (bit_offset, length)? as u16)
}
fn get_i16(self, bit_offset: u32, length: u32) -> Result<i16> {
if length > 16 {
return Err(s!(LEN_TOO_BIG_MSG) + "i16");
}
Ok(self.get_i32 (bit_offset, length)? as i16)
}
fn get_u32(self, bit_offset: u32, length: u32) -> Result<u32> {
check_range!(bit_offset, length);
let mut copy = self;
copy <<= bit_offset;
copy >>= 32 - length;
Ok(copy)
}
fn get_i32(self, bit_offset: u32, length: u32) -> Result<i32> {
check_range!(bit_offset, length);
let mut copy = self as i32;
copy <<= bit_offset;
copy >>= 32 - length;
Ok(copy)
}
#[inline]
fn get_u64(self, bit_offset: u32, length: u32) -> Result<u64> {
Ok(self.get_u32 (bit_offset, length)? as u64)
}
#[inline]
fn get_i64(self, bit_offset: u32, length: u32) -> Result<i64> {
Ok(self.get_i32 (bit_offset, length)? as i64)
}
}
impl ExtractBitsFromIntegralTypes for i32 {
#[inline]
fn get_u8(self, bit_offset: u32, length: u32) -> Result<u8> {
(self as u32).get_u8 (bit_offset, length)
}
#[inline]
fn get_i8(self, bit_offset: u32, length: u32) -> Result<i8> {
(self as u32).get_i8 (bit_offset, length)
}
#[inline]
fn get_u16(self, bit_offset: u32, length: u32) -> Result<u16> {
(self as u32).get_u16 (bit_offset, length)
}
#[inline]
fn get_i16(self, bit_offset: u32, length: u32) -> Result<i16> {
(self as u32).get_i16 (bit_offset, length)
}
#[inline]
fn get_u32(self, bit_offset: u32, length: u32) -> Result<u32> {
(self as u32).get_u32 (bit_offset, length)
}
#[inline]
fn get_i32(self, bit_offset: u32, length: u32) -> Result<i32> {
(self as u32).get_i32 (bit_offset, length)
}
#[inline]
fn get_u64(self, bit_offset: u32, length: u32) -> Result<u64> {
(self as u32).get_u64 (bit_offset, length)
}
#[inline]
fn get_i64(self, bit_offset: u32, length: u32) -> Result<i64> {
(self as u32).get_i64 (bit_offset, length)
}
}
impl ExtractBitsFromIntegralTypes for u64 {
fn get_u8(self, bit_offset: u32, length: u32) -> Result<u8> {
if length > 8 {
return Err(s!(LEN_TOO_BIG_MSG) + "u8");
}
Ok(self.get_u64 (bit_offset, length)? as u8)
}
fn get_i8(self, bit_offset: u32, length: u32) -> Result<i8> {
if length > 8 {
return Err(s!(LEN_TOO_BIG_MSG) + "i8");
}
Ok(self.get_i64 (bit_offset, length)? as i8)
}
fn get_u16(self, bit_offset: u32, length: u32) -> Result<u16> {
if length > 16 {
return Err(s!(LEN_TOO_BIG_MSG) + "u16");
}
Ok(self.get_u64 (bit_offset, length)? as u16)
}
fn get_i16(self, bit_offset: u32, length: u32) -> Result<i16> {
if length > 16 {
return Err(s!(LEN_TOO_BIG_MSG) + "i16");
}
Ok(self.get_i64 (bit_offset, length)? as i16)
}
fn get_u32(self, bit_offset: u32, length: u32) -> Result<u32> {
if length > 32 {
return Err(s!(LEN_TOO_BIG_MSG) + "u32");
}
Ok(self.get_u64 (bit_offset, length)? as u32)
}
fn get_i32(self, bit_offset: u32, length: u32) -> Result<i32> {
if length > 32 {
return Err(s!(LEN_TOO_BIG_MSG) + "i32");
}
Ok(self.get_i64 (bit_offset, length)? as i32)
}
fn get_u64(self, bit_offset: u32, length: u32) -> Result<u64> {
check_range!(bit_offset, length);
let mut copy = self;
copy <<= bit_offset;
copy >>= 64 - length;
Ok(copy)
}
fn get_i64(self, bit_offset: u32, length: u32) -> Result<i64> {
check_range!(bit_offset, length);
let mut copy = self as i64;
copy <<= bit_offset;
copy >>= 64 - length;
Ok(copy)
}
}
impl ExtractBitsFromIntegralTypes for i64 {
#[inline]
fn get_u8(self, bit_offset: u32, length: u32) -> Result<u8> {
(self as u64).get_u8 (bit_offset, length)
}
#[inline]
fn get_i8(self, bit_offset: u32, length: u32) -> Result<i8> {
(self as u64).get_i8 (bit_offset, length)
}
#[inline]
fn get_u16(self, bit_offset: u32, length: u32) -> Result<u16> {
(self as u64).get_u16 (bit_offset, length)
}
#[inline]
fn get_i16(self, bit_offset: u32, length: u32) -> Result<i16> {
(self as u64).get_i16 (bit_offset, length)
}
#[inline]
fn get_u32(self, bit_offset: u32, length: u32) -> Result<u32> {
(self as u64).get_u32 (bit_offset, length)
}
#[inline]
fn get_i32(self, bit_offset: u32, length: u32) -> Result<i32> {
(self as u64).get_i32 (bit_offset, length)
}
#[inline]
fn get_u64(self, bit_offset: u32, length: u32) -> Result<u64> {
(self as u64).get_u64 (bit_offset, length)
}
#[inline]
fn get_i64(self, bit_offset: u32, length: u32) -> Result<i64> {
(self as u64).get_i64 (bit_offset, length)
}
}
pub trait ExtractBitsFromVecU8 {
fn get_u8(&self, byte_offset: u32, start: u32, length: u32) -> Result<u8>;
fn get_i8(&self, byte_offset: u32, start: u32, length: u32) -> Result<i8>;
fn get_u16(&self, byte_offset: u32, start: u32, length: u32) -> Result<u16>;
fn get_i16(&self, byte_offset: u32, start: u32, length: u32) -> Result<i16>;
fn get_u32(&self, byte_offset: u32, start: u32, length: u32) -> Result<u32>;
fn get_i32(&self, byte_offset: u32, start: u32, length: u32) -> Result<i32>;
}
impl ExtractBitsFromVecU8 for Vec<u8> {
fn get_u8(&self, byte_offset: u32, bit_offset: u32, length: u32) -> Result<u8> {
if length == 0 { return Err(s!(LEN_ZERO)); };
if length <= 8 {
if self.len() as u32 * 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 as usize];
copy = u8::from_be(copy);
copy <<= bit_offset_copy;
copy >>= 8 - length;
return Ok(copy);
} else {
let copy1: u8 = self[byte_offset_copy as usize];
let mut copy1_as_u16: u16 = copy1 as u16;
copy1_as_u16 <<= 8;
let copy2: u8 = self[byte_offset_copy as usize + 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: u32, bit_offset: u32, length: u32) -> Result<i8> {
if length == 0 { return Err(s!(LEN_ZERO)); };
if length <= 8 {
if self.len() as u32 * 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 usize] 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 usize] as i8;
let mut copy1_as_i16: i16 = copy1 as i16;
copy1_as_i16 <<= 8;
let copy2: i8 = self[byte_offset_copy as usize + 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: u32, bit_offset: u32, length: u32) -> Result<u16> {
if length == 0 { return Err(s!(LEN_ZERO)); };
if length <= 16 {
if self.len() as u32 * 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 usize] 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 usize] as u16;
copy1 <<= 8;
let copy2 = self[byte_offset_copy as usize + 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 usize] as u32;
copy1 <<= 16;
let mut copy2 = self[byte_offset_copy as usize + 1] as u32;
copy2 <<= 8;
let copy3 = self[byte_offset_copy as usize + 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: u32, bit_offset: u32, length: u32) -> Result<i16> {
if length == 0 { return Err(s!(LEN_ZERO)); };
if length <= 16 {
if self.len() as u32 * 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 usize] 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 usize] as i16;
copy1 <<= 8;
let copy2 = self[byte_offset_copy as usize + 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 usize] as i32;
copy1 <<= 16;
let mut copy2 = self[byte_offset_copy as usize + 1] as i32;
copy2 <<= 8;
let copy3 = self[byte_offset_copy as usize + 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: u32, bit_offset: u32, length: u32) -> Result<u32> {
if length == 0 { return Err(s!(LEN_ZERO)); };
if length <= 32 {
if self.len() as u32 * 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 usize] 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 usize] as u32;
copy1 <<= 8;
let copy2 = self[byte_offset_copy as usize + 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 usize] as u32;
copy1 <<= 16;
let mut copy2 = self[byte_offset_copy as usize + 1] as u32;
copy2 <<= 8;
let copy3 = self[byte_offset_copy as usize + 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 usize] as u32;
copy1 <<= 24;
let mut copy2 = self[byte_offset_copy as usize + 1] as u32;
copy2 <<= 16;
let mut copy3 = self[byte_offset_copy as usize + 2] as u32;
copy3 <<= 8;
let copy4 = self[byte_offset_copy as usize + 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 usize] as u64;
copy1 <<= 32;
let mut copy2 = self[byte_offset_copy as usize + 1] as u64;
copy2 <<= 24;
let mut copy3 = self[byte_offset_copy as usize + 2] as u64;
copy3 <<= 16;
let mut copy4 = self[byte_offset_copy as usize + 3] as u64;
copy4 <<= 8;
let copy5 = self[byte_offset_copy as usize + 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: u32, bit_offset: u32, length: u32) -> Result<i32> {
if length == 0 { return Err(s!(LEN_ZERO)); };
if length <= 32 {
if self.len() as u32 * 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 usize] 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 usize] as i32;
copy1 <<= 8;
let copy2 = self[byte_offset_copy as usize + 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 usize] as i32;
copy1 <<= 16;
let mut copy2 = self[byte_offset_copy as usize + 1] as i32;
copy2 <<= 8;
let copy3 = self[byte_offset_copy as usize + 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 usize] as i32;
copy1 <<= 24;
let mut copy2 = self[byte_offset_copy as usize + 1] as i32;
copy2 <<= 16;
let mut copy3 = self[byte_offset_copy as usize + 2] as i32;
copy3 <<= 8;
let copy4 = self[byte_offset_copy as usize + 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 usize] as i64;
copy1 <<= 32;
let mut copy2 = self[byte_offset_copy as usize + 1] as i64;
copy2 <<= 24;
let mut copy3 = self[byte_offset_copy as usize + 2] as i64;
copy3 <<= 16;
let mut copy4 = self[byte_offset_copy as usize + 3] as i64;
copy4 <<= 8;
let copy5 = self[byte_offset_copy as usize + 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 InsertIntoSizedIntegerTypes {
fn set<T>(self, bit_offset: u32, length: u32, value: T) -> Result<Self>
where Self: std::marker::Sized, T: std::marker::Sized, T: SignedInfo,
T: num::cast::AsPrimitive<u8>, T: num::cast::AsPrimitive<i8>,
T: num::cast::AsPrimitive<u16>, T: num::cast::AsPrimitive<i16>,
T: num::cast::AsPrimitive<u32>, T: num::cast::AsPrimitive<i32>,
T: num::cast::AsPrimitive<u64>, T: num::cast::AsPrimitive<i64>,
T : std::string::ToString;
}
macro_rules! def_set_fn {
($t:ty) => (
fn set<T>(self, bit_offset: u32, length: u32, value: T) -> Result<Self>
where Self: std::marker::Sized, T: std::marker::Sized, T: SignedInfo,
T: num::cast::AsPrimitive<u8>, T: num::cast::AsPrimitive<i8>,
T: num::cast::AsPrimitive<u16>, T: num::cast::AsPrimitive<i16>,
T: num::cast::AsPrimitive<u32>, T: num::cast::AsPrimitive<i32>,
T: num::cast::AsPrimitive<u64>, T: num::cast::AsPrimitive<i64>,
T : std::string::ToString {
if length > std::mem::size_of::<Self>() as u32 * 8 {
return Err(s!(LEN_TOO_BIG_MSG) + TypeInfo::type_of(&self));
}
check_range!(bit_offset, length);
if value.is_signed() {
let n = n_required_bits_for_a_signed_int(value.as_());
if n > length {
return Err(format!("Failed to 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_());
if n > length {
return Err(format!("Failed to insert {} as a {} bit unsigned integer variable, since it requires at least {} bits.",
&value.to_string(), &length.to_string(), &n.to_string()))
}
}
let mut result = self;
let mut value_copy : Self = value.as_();
let shift = std::mem::size_of_val(&value_copy) as u8 * 8 - (bit_offset + length) as u8;
value_copy <<= shift;
for i in bit_offset .. bit_offset + 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 InsertIntoSizedIntegerTypes for u8 { def_set_fn!(u8); }
impl InsertIntoSizedIntegerTypes for i8 { def_set_fn!(i8); }
impl InsertIntoSizedIntegerTypes for u16 { def_set_fn!(u8); }
impl InsertIntoSizedIntegerTypes for i16 { def_set_fn!(i8); }
impl InsertIntoSizedIntegerTypes for u32 { def_set_fn!(u8); }
impl InsertIntoSizedIntegerTypes for i32 { def_set_fn!(i8); }
impl InsertIntoSizedIntegerTypes for u64 { def_set_fn!(u8); }
impl InsertIntoSizedIntegerTypes for i64 { def_set_fn!(i8); }
pub trait InsertBitsIntoVecU8 {
fn set<T>(&mut self, byte_offset: u32, bit_offset: u32, length: u32, value: T) -> Result<()>
where Self: std::marker::Sized, T: std::marker::Sized, T: SignedInfo,
T: num::cast::AsPrimitive<u8>, T: num::cast::AsPrimitive<i8>,
T: num::cast::AsPrimitive<u16>, T: num::cast::AsPrimitive<i16>,
T: num::cast::AsPrimitive<u32>, T: num::cast::AsPrimitive<i32>,
T: num::cast::AsPrimitive<u64>, T: num::cast::AsPrimitive<i64>,
T : std::string::ToString, T: SingleBits + Copy;
}
impl InsertBitsIntoVecU8 for Vec<u8> {
fn set<T>(&mut self, byte_offset: u32, bit_offset: u32, length: u32, value: T) -> Result<()>
where Self: std::marker::Sized, T: std::marker::Sized, T: SignedInfo,
T: num::cast::AsPrimitive<u8>, T: num::cast::AsPrimitive<i8>,
T: num::cast::AsPrimitive<u16>, T: num::cast::AsPrimitive<i16>,
T: num::cast::AsPrimitive<u32>, T: num::cast::AsPrimitive<i32>,
T: num::cast::AsPrimitive<u64>, T: num::cast::AsPrimitive<i64>,
T : std::string::ToString, T: SingleBits + Copy {
if length == 0 { return Err(s!(LEN_ZERO)); };
if byte_offset * 8 + bit_offset + length > self.len() as u32 * 8 {
return Err(s!(OUT_OF_RANGE_MSG));
}
if value.is_signed() {
let n = n_required_bits_for_a_signed_int(value.as_());
if n > length {
return Err(format!("Failed to 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_());
if n > length {
return Err(format!("Failed to insert {} as a {} bit unsigned integer variable, since it requires at least {} bits.",
&value.to_string(), &length.to_string(), &n.to_string()))
}
}
let first_relevant_byte_index = byte_offset + bit_offset / 8;
let last_relevant_byte_index = byte_offset + (bit_offset + length - 1) / 8;
let mut bit_counter = length;
let mut read_bit_index = std::mem::size_of::<T>() as u32 * 8 - length;
let mut write_bit_index = bit_offset % 8;
for byte_index in first_relevant_byte_index .. last_relevant_byte_index + 1 {
let mut copy = self[byte_index as usize];
while bit_counter > 0 {
if value.get_bit(read_bit_index)? {
copy = copy.set_bit(write_bit_index)?;
} else {
copy = copy.clear_bit(write_bit_index)?;
}
read_bit_index += 1;
write_bit_index += 1;
bit_counter -= 1;
if write_bit_index % 8 == 0 {
write_bit_index = 0;
break;
}
}
self[byte_index as usize] = copy;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[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);
}
#[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(1, 2, b).unwrap(), 0b0110_0000);
let a : u8 = 0b0110_0011;
let b : u8 = 0b0000_0010;
assert_eq!(a.set(5, 2, b).unwrap(), 0b0110_0101);
match a.set(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(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 : u8 = 5;
match a.set(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Failed to 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(5, 2, b).unwrap(), 0b0110_0101);
let b : i8 = -2;
assert_eq!( 0b1111_1110 as u8 as i8, b);
assert_eq!(a.set(5, 2, b).unwrap(), 0b0110_0101);
match a.set(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(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(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Failed to 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(1, 2, b).unwrap(), 0b0110_0000_0000_0000);
let a : u16 = 0b0110_0011_0000_0110;
let b : u8 = 0b0000_0010;
assert_eq!(a.set(5, 2, b).unwrap(), 0b0110_0101_0000_0110);
assert_eq!(a.set(12, 2, b).unwrap(), 0b0110_0011_0000_1010);
match a.set(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(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 : u8 = 5;
match a.set(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Failed to insert 5 as a 2 bit unsigned integer variable, since it requires at least 3 bits.")),
}
let b : i8 = 0b0000_0010;
assert_eq!(a.set(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(5, 2, b).unwrap(), 0b0110_0101_0000_0110);
assert_eq!(a.set(12, 2, b).unwrap(), 0b0110_0011_0000_1010);
match a.set(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(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(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Failed to 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(1, 2, b).unwrap(), 0b0110_0000_0000_0000_0000_0000_0000_0000);
let a : u32 = 0b0110_0011_0000_0110_0110_0011_0000_0110;
let b : u8 = 0b0000_0010;
assert_eq!(a.set(5, 2, b).unwrap(), 0b0110_0101_0000_0110_0110_0011_0000_0110);
assert_eq!(a.set(28, 2, b).unwrap(), 0b0110_0011_0000_0110_0110_0011_0000_1010);
match a.set(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(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 : u8 = 5;
match a.set(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Failed to insert 5 as a 2 bit unsigned integer variable, since it requires at least 3 bits.")),
}
let b : i8 = 0b0000_0010;
assert_eq!(a.set(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(5, 2, b).unwrap(), 0b0110_0101_0000_0110_0110_0011_0000_0110);
assert_eq!(a.set(28, 2, b).unwrap(), 0b0110_0011_0000_0110_0110_0011_0000_1010);
match a.set(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(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(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Failed to 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(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_0110_0110_0011_0000_0110_0000_0000_0000_0000_0000_0000_0000_0000;
let b : u8 = 0b0000_0010;
assert_eq!(a.set(5, 2, b).unwrap(), 0b0110_0101_0000_0110_0110_0011_0000_0110_0000_0000_0000_0000_0000_0000_0000_0000);
assert_eq!(a.set(60, 2, b).unwrap(), 0b0110_0011_0000_0110_0110_0011_0000_0110_0000_0000_0000_0000_0000_0000_0000_1000);
match a.set(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(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 : u8 = 5;
match a.set(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Failed to insert 5 as a 2 bit unsigned integer variable, since it requires at least 3 bits.")),
}
let b : i8 = 0b0000_0010;
assert_eq!(a.set(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(5, 2, b).unwrap(), 0b0110_0101_0000_0110_0110_0011_0000_0110_0000_0000_0000_0000_0000_0000_0000_0000);
assert_eq!(a.set(60, 2, b).unwrap(), 0b0110_0011_0000_0110_0110_0011_0000_0110_0000_0000_0000_0000_0000_0000_0000_1000);
match a.set(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(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(5, 2, b) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!("Failed to 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(1, 2, b).unwrap(), 0b0110_0000);
let a : u8 = 0b0110_0011;
let b : u16 = 0b0000_0000_0000_0010;
assert_eq!(a.set(5, 2, b).unwrap(), 0b0110_0101);
match a.set(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(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(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(5, 2, b).unwrap(), 0b0110_0101);
match a.set(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(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(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(5, 2, b).unwrap(), 0b0110_0101_0000_1110);
assert_eq!(a.set(12, 2, b).unwrap(), 0b0110_0011_0000_1010);
match a.set(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(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 : i16 = 0b0000_0000_0000_0010;
assert_eq!(a.set(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(5, 2, b).unwrap(), 0b0110_0101_0000_1110);
assert_eq!(a.set(12, 2, b).unwrap(), 0b0110_0011_0000_1010);
match a.set(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(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(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(5, 2, b).unwrap(), 0b0110_0101_0000_1110_0000_0000_0000_0000);
assert_eq!(a.set(28, 2, b).unwrap(), 0b0110_0011_0000_1110_0000_0000_0000_1000);
match a.set(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(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 : i16 = 0b0000_0000_0000_0010;
assert_eq!(a.set(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(5, 2, b).unwrap(), 0b0110_0101_0000_1110_0000_0000_0000_0000);
assert_eq!(a.set(28, 2, b).unwrap(), 0b0110_0011_0000_1110_0000_0000_0000_1000);
match a.set(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(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(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(5, 2, b).unwrap(), 0b0110_0101_0000_1110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
assert_eq!(a.set(60, 2, b).unwrap(), 0b0110_0011_0000_1110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1000);
match a.set(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(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 : i16 = 0b0000_0000_0000_0010;
assert_eq!(a.set(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(5, 2, b).unwrap(), 0b0110_0101_0000_1110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
assert_eq!(a.set(60, 2, b).unwrap(), 0b0110_0011_0000_1110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1000);
match a.set(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(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(1, 2, b).unwrap(), 0b0110_0000);
let a : u8 = 0b0110_0011;
let b : u32 = 0b0000_0000_0000_0010;
assert_eq!(a.set(5, 2, b).unwrap(), 0b0110_0101);
match a.set(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(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(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(5, 2, b).unwrap(), 0b0110_0101);
match a.set(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(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(1, 2, b).unwrap(), 0b0110_0000_0000_0000);
let a : u16 = 0b0000_0000_0110_0011;
let b : u32 = 2;
assert_eq!(a.set(5, 2, b).unwrap(), 0b0000_0100_0110_0011);
assert_eq!(a.set(12, 2, b).unwrap(), 0b0000_0000_0110_1011);
match a.set(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(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 : i32 = 2;
assert_eq!(a.set(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(5, 2, b).unwrap(), 0b0000_0100_0110_0011);
assert_eq!(a.set(12, 2, b).unwrap(), 0b0000_0000_0110_1011);
match a.set(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(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(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(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000);
assert_eq!(a.set(28, 2, b).unwrap(), 0b0000_0000_0110_0011_0000_0000_0000_1000);
match a.set(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(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 : i32 = 2;
assert_eq!(a.set(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(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000);
assert_eq!(a.set(28, 2, b).unwrap(), 0b0000_0000_0110_0011_0000_0000_0000_1000);
match a.set(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(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(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(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
assert_eq!(a.set(60, 2, b).unwrap(), 0b0000_0000_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1000);
match a.set(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(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 : i32 = 2;
assert_eq!(a.set(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(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000);
assert_eq!(a.set(60, 2, b).unwrap(), 0b0000_0000_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1000);
match a.set(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(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(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(5, 2, b).unwrap(), 0b0110_0101);
match a.set(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(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 : i64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set(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(5, 2, b).unwrap(), 0b0110_0101);
match a.set(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(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(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(5, 2, b).unwrap(), 0b0000_0100_0110_0011);
assert_eq!(a.set(12, 2, b).unwrap(), 0b0000_0000_0110_1011);
match a.set(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(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 : i64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set(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(5, 2, b).unwrap(), 0b0000_0100_0110_0011);
assert_eq!(a.set(12, 2, b).unwrap(), 0b0000_0000_0110_1011);
match a.set(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(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(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(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000);
assert_eq!(a.set(28, 2, b).unwrap(), 0b0000_0000_0110_0011_0000_0000_0000_1000);
match a.set(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(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 : i64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set(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(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000);
assert_eq!(a.set(28, 2, b).unwrap(), 0b0000_0000_0110_0011_0000_0000_0000_1000);
match a.set(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(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(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_0110_0000;
let b : u64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0110_0000);
assert_eq!(a.set(45, 2, b).unwrap(), 0b0000_0000_0110_0011_0000_0000_0000_0000_0000_0000_0000_0100_0000_0000_0110_0000);
match a.set(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(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 : i64 = 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010;
assert_eq!(a.set(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0110_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(5, 2, b).unwrap(), 0b0000_0100_0110_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0110_0000);
assert_eq!(a.set(45, 2, b).unwrap(), 0b0000_0000_0110_0011_0000_0000_0000_0000_0000_0000_0000_0100_0000_0000_0110_0000);
match a.set(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(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_into_a_vector() {
let mut v: Vec<u8> = vec!{ 0x48, 0x61, 0x6C, 0x6C, 0x6F };
let a : u8 = 3;
let bar = v.set(0, 0, 2, a);
assert_eq!(bar.unwrap(), ());
assert_eq!(v[0], 0b1100_1000);
let mut v: Vec<u8> = vec!{ 0x48, 0x61, 0x6C, 0x6C, 0x6F };
let a : u8 = 3;
let bar = v.set(1, 0, 2, a);
assert_eq!(bar.unwrap(), ());
assert_eq!(v[1], 0b1110_0001);
let mut v: Vec<u8> = vec!{ 0x48, 0x61, 0x6C, 0x6C, 0x6F };
let a : u8 = 3;
let bar = v.set(1, 15, 2, a);
assert_eq!(bar.unwrap(), ());
assert_eq!(v[2], 0b0110_1101);
assert_eq!(v[3], 0b1110_1100);
let mut v: Vec<u8> = vec!{ 0x48, 0x61, 0x00, 0x6C, 0x6F, 0x00, 0xFF, 0x0F };
let a : i32 = 0b0000_0000_0000_0101_0101_0101_0101_0101;
let bar = v.set(2, 15, 20, a);
assert_eq!(bar.unwrap(), ());
assert_eq!(v[2], 0);
assert_eq!(v[3], 0b0110_1100);
assert_eq!(v[4], 0b1010_1010);
assert_eq!(v[5], 0b1010_1010);
assert_eq!(v[6], 0b1011_1111);
let mut v: Vec<u8> = vec!{ 0x00, 0x00, 0x00 };
let i = v.len() as u32 - 1;
let bar = v.set(i, 7, 1, 1);
assert_eq!(bar.unwrap(), ());
assert_eq!(v[i as usize], 0x01);
match v.set(i, 8, 1, 1) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
match v.set(i, 7, 2, 1) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
match v.set(0, i * 8 + 7, 2, 1) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
match v.set(i + 1, 0, 1, 1) {
Ok(_) => panic!("The range check failed to detect invalid range"),
Err(e) => assert_eq!(e, s!(OUT_OF_RANGE_MSG)),
}
match v.set(0, 0, 1, 3 as u32) {
Ok(_) => panic!("The range check failed to detect invalid length"),
Err(e) => assert_eq!(e, s!("Failed to insert 3 as a 1 bit unsigned integer variable, since it requires at least 2 bits.")),
}
}
}