#![expect(clippy::unwrap_used, reason = "tests")]
use bitref::{BitSlice, IndexOutOfBounds};
use core::ops::Range;
const BYTES: [u8; 2] = [0xa0, 0x0a];
const BITS: [bool; 16] = [
true, false, true, false, false, false, false, false, false, false, false, false, true, false,
true, false,
];
#[test]
fn debug() {
let bits = BitSlice::new(&BYTES);
assert_eq!(&format!("{bits:?}"), "BitSlice([1010000000001010])");
let bits2 = &bits[1..14];
assert_eq!(&format!("{bits2:?}"), "BitSlice([0100000000010])");
}
#[test]
fn display_ioob_error() {
assert_eq!(IndexOutOfBounds.to_string(), "index out of bounds");
}
#[test]
fn from_new_equivalence() {
assert_eq!(BitSlice::new(&BYTES), <&BitSlice>::from(BYTES.as_slice()));
}
#[test]
fn from_new_equivalence_mut() {
let mut bytes1 = BYTES;
let mut bytes2 = BYTES;
assert_eq!(
BitSlice::new_mut(&mut bytes1),
<&mut BitSlice>::from(bytes2.as_mut_slice())
);
}
#[test]
fn first() {
assert!(BitSlice::EMPTY.first().is_none());
assert!(!BitSlice::new(&[0]).first().unwrap());
}
#[test]
fn last() {
assert!(BitSlice::EMPTY.last().is_none());
assert!(BitSlice::new(&[0, 1]).last().unwrap());
}
#[test]
fn get_bit() {
let bits = BitSlice::new(&BYTES);
for (i, expected) in BITS.into_iter().enumerate() {
assert_eq!(bits.get_bit(i).unwrap(), expected);
}
assert!(bits.get_bit(bits.len()).is_err());
}
#[test]
fn get_slice() {
let bits = BitSlice::new(&BYTES);
for i in 0..BITS.len() {
for j in i..BITS.len() {
let bitslice = bits.get_slice(i..j).unwrap();
verify_against_expected(bitslice, i..j);
}
}
assert!(bits.get_slice(0..(BITS.len() + 1)).is_err());
}
#[test]
fn get_mut_slice() {
let mut bytes = BYTES;
let bits = BitSlice::new_mut(&mut bytes);
for i in 0..BITS.len() {
for j in i..BITS.len() {
let bitslice = bits.get_mut_slice(i..j).unwrap();
verify_against_expected(bitslice, i..j);
}
}
assert!(bits.get_mut_slice(0..(BITS.len() + 1)).is_err());
}
#[test]
fn index_usize() {
let bits = BitSlice::new(&BYTES);
for (i, expected) in BITS.into_iter().enumerate() {
assert_eq!(bits[i], expected);
}
}
#[test]
#[should_panic]
fn index_usize_oob() {
let bits = BitSlice::new(&BYTES);
let _ = bits[bits.len()];
}
#[test]
fn index_range_slicing() {
let bits = BitSlice::new(&BYTES);
for i in 0..BITS.len() {
for j in i..BITS.len() {
verify_against_expected(&bits[i..j], i..j);
}
}
}
#[test]
#[allow(clippy::redundant_slicing)]
fn index_range_full_slicing() {
let bits = BitSlice::new(&BYTES);
verify_against_expected(&bits[..], 0..BITS.len());
}
#[test]
fn index_range_from_slicing() {
let bits = BitSlice::new(&BYTES);
for i in 0..BITS.len() {
verify_against_expected(&bits[i..], i..BITS.len());
}
}
#[test]
fn index_range_to_slicing() {
let bits = BitSlice::new(&BYTES);
for j in 0..BITS.len() {
verify_against_expected(&bits[..j], 0..j);
}
}
#[test]
#[allow(clippy::unnecessary_mut_passed)]
fn index_mut_range_slicing() {
let mut bytes = BYTES;
let bits = BitSlice::new_mut(&mut bytes);
for i in 0..BITS.len() {
for j in i..BITS.len() {
verify_against_expected(&mut bits[i..j], i..j);
}
}
}
#[test]
#[allow(clippy::unnecessary_mut_passed)]
fn index_mut_range_full_slicing() {
let mut bytes = BYTES;
let bits = BitSlice::new_mut(&mut bytes);
verify_against_expected(&mut bits[..], 0..BITS.len());
}
#[test]
#[allow(clippy::unnecessary_mut_passed)]
fn index_mut_range_from_slicing() {
let mut bytes = BYTES;
let bits = BitSlice::new_mut(&mut bytes);
for i in 0..BITS.len() {
verify_against_expected(&mut bits[i..], i..BITS.len());
}
}
#[test]
#[allow(clippy::unnecessary_mut_passed)]
fn index_mut_range_to_slicing() {
let mut bytes = BYTES;
let bits = BitSlice::new_mut(&mut bytes);
for j in 0..BITS.len() {
verify_against_expected(&mut bits[..j], 0..j);
}
}
#[test]
fn is_empty() {
assert!(BitSlice::EMPTY.is_empty());
assert!(!BitSlice::new(&[0]).is_empty());
assert!(!BitSlice::new(&BYTES).is_empty());
}
#[test]
fn len() {
assert_eq!(BitSlice::EMPTY.len(), 0);
assert_eq!(BitSlice::new(&[0]).len(), 8);
assert_eq!(BitSlice::new(&BYTES).len(), 16);
}
#[test]
fn partial_eq() {
let zeros = BitSlice::new(&[0, 0]);
let bits = BitSlice::new(&BYTES);
assert_ne!(BitSlice::EMPTY, bits);
assert_ne!(zeros, bits);
assert_eq!(BitSlice::EMPTY, BitSlice::EMPTY);
assert_eq!(zeros, zeros);
assert_eq!(bits, bits);
}
#[test]
fn set_bit() {
let mut bytes = [0x0, 0x0];
let bits = BitSlice::new_mut(&mut bytes);
for (i, bit) in BITS.into_iter().enumerate() {
bits.set_bit(i, bit).unwrap();
}
assert!(bits.set_bit(bits.len(), true).is_err());
assert_eq!(bytes, BYTES);
}
#[test]
fn split_first() {
assert!(BitSlice::EMPTY.split_first().is_none());
let bits = BitSlice::new(&[0b10000000]);
let (first, rest) = bits.split_first().unwrap();
assert!(first);
assert_eq!(rest, &BitSlice::new(&[0])[..7]);
}
#[test]
fn split_last() {
assert!(BitSlice::EMPTY.split_last().is_none());
let bits = BitSlice::new(&[1]);
let (last, rest) = bits.split_last().unwrap();
assert!(last);
assert_eq!(rest, &BitSlice::new(&[0])[..7]);
}
#[test]
fn replace_bit() {
let mut bytes = [!BYTES[0], !BYTES[1]];
let bits = BitSlice::new_mut(&mut bytes);
for (i, bit) in BITS.into_iter().enumerate() {
let old = bits.replace_bit(i, bit).unwrap();
assert_eq!(old, !bit);
}
assert_eq!(bytes, BYTES);
}
#[track_caller]
fn verify_against_expected(bitslice: &BitSlice, range: Range<usize>) {
let coreslice = &BITS[range];
assert_eq!(bitslice.len(), coreslice.len());
for k in 0..bitslice.len() {
assert_eq!(bitslice.get_bit(k).unwrap(), coreslice[k]);
}
}