bloom-filter-yss 0.2.0

Simple bloom filter for me or you
Documentation
use std::ops::Index;

pub struct BitArray {
    byte_array: Vec<u8>,
    pub size: usize,
}

impl BitArray {
    pub fn new(size: usize) -> Self {
        let num_bytes = (size + 7) / 8;
        Self {
            byte_array: vec![0; num_bytes],
            size,
        }
    }

    pub fn set(&mut self, index: usize, value: bool) {
        let (byte_index, bit_offset) = self.get_byte_position(index);
        let mask = 1 << (7 - bit_offset);

        if value {
            self.byte_array[byte_index] |= mask;
        } else {
            self.byte_array[byte_index] &= !mask;
        }
    }

    pub fn get_bit(&self, index: usize) -> bool {
        self[index]
    }

    pub fn get_byte_position(&self, bit_index: usize) -> (usize, usize) {
        if bit_index >= self.size {
            panic!("Index out of bounds: must less than {}", self.size);
        }
        let index = bit_index / 8;
        let offset = bit_index % 8;
        (index, offset)
    }
}

impl Index<usize> for BitArray {
    type Output = bool;

    fn index(&self, index: usize) -> &Self::Output {
        let (byte_index, bit_offset) = self.get_byte_position(index);
        let mask = 1 << (7 - bit_offset);

        if (self.byte_array[byte_index] & mask) != 0 {
            &true
        } else {
            &false
        }
    }
}

impl std::fmt::Display for BitArray {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        let mut bits = vec!['0'; self.size];

        for (index, bit) in bits.iter_mut().enumerate() {
            let (byte_index, bit_offset) = self.get_byte_position(index);
            let bit_value = (self.byte_array[byte_index] >> (7 - bit_offset)) & 1;
            *bit = if bit_value == 1 { '1' } else { '0' };
        }

        write!(f, "{}", bits.iter().collect::<String>())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_bit_array() {
        let mut bit_array = BitArray::new(10);
        bit_array.set(5, true);
        bit_array.set(9, true);
        println!("{}", bit_array);
        assert!(bit_array[5]);
        assert!(bit_array[9]);
        assert!(!bit_array[0]);
        bit_array.set(0, true);
        bit_array.set(5, false);
        println!("{}", bit_array);
        assert!(bit_array[0]);
        assert!(!bit_array[5]);
    }

    #[test]
    fn test_out_of_bound_set_panic() {
        let result = std::panic::catch_unwind(|| {
            let mut bit_array = BitArray::new(10);
            bit_array.set(10, true);
        });
        assert!(result.is_err())
    }

    #[test]
    #[should_panic(expected = "Index out of bounds: must less than 5")]
    fn test_out_of_bound_get_panic() {
        let bit_array = BitArray::new(5);
        assert!(!bit_array[6]);
    }
}