#![allow(clippy::needless_range_loop)]
use std::mem;
pub fn byte_to_bits(value: u8) -> [bool; 8] {
let mut bits = [false; 8];
for i in 0..8 {
bits[i] = value & (1 << i) != 0;
}
bits
}
pub fn bytes_to_bits(bytes: &[u8]) -> Vec<bool> {
let mut bits: Vec<bool> = vec![false; bytes.len() * 8];
for i in 0..bytes.len() {
let bit_index = i * 8;
bits[bit_index..(bit_index + 8)].copy_from_slice(&byte_to_bits(bytes[i]));
}
bits
}
pub fn checked_bits_to_uint(bits: &[bool]) -> Option<usize> {
const PTR_SIZE_BITS: usize = mem::size_of::<usize>() * 8;
if bits.len() > PTR_SIZE_BITS {
None
} else {
let mut value: usize = 0;
for i in 0..bits.len() {
value |= usize::from(bits[i]) << i;
}
Some(value)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
pub fn test_bytes_to_bits() {
let bytes = [1u8, 127];
let bits = bytes_to_bits(&bytes);
assert_eq!(bits, [
true, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false
]);
}
#[test]
pub fn test_checked_bits_to_uint() {
let bits = [true, false, false, false, false, false, false, false];
let uint = checked_bits_to_uint(&bits).unwrap();
assert_eq!(uint, 1);
let bits = [
true, false, false, false, false, false, false, false, true, false, false, false, false, false, false,
false,
];
let uint = checked_bits_to_uint(&bits).unwrap();
assert_eq!(uint, 257);
let bits = [false; mem::size_of::<usize>() * 8 + 1];
assert!(checked_bits_to_uint(&bits).is_none());
}
}