bigwise 0.4.0

Bitwise operations on fixed-size, arbitrary big buffer of bytes.
Documentation
use Bigwise;
use BitsIter;
use std::fmt::{self, Debug, Formatter};
use std::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
use rand::{Rand, Rng};

/// A `Bigwise` type composed of 64 bits.
///
/// Wraps a `u64`
///
#[derive(Copy, Clone, Eq, PartialEq, Hash, Default, Ord, PartialOrd)]
pub struct Bw64(u64);

impl Bigwise for Bw64 {

    fn size() -> u32 {
        64
    }

    fn empty() -> Self {
        Bw64(0)
    }

    fn full() -> Self {
        Bw64(!0)
    }

    fn from_bytes(bytes: &[u8]) -> Self {
        let mut val = 0u64;
        for (i, &b) in bytes.iter().rev().take(8).enumerate() {
            val |= (b as u64) << (8*i);
        }
        Bw64(val)
    }

    fn to_bytes(self) -> Vec<u8> {
        let nb_bytes = (Self::size() / 8) as usize;
        let mut res = Vec::with_capacity(nb_bytes);
        for i in (0..nb_bytes).rev() {
            res.push(((self.0 >> (8*i)) & 0xFF) as u8);
        }
        res
    }

    fn get(self, i: u32) -> bool {
        if i >= Self::size() {
            false
        } else {
            (self.0 >> i) & 1 > 0
        }
    }

    fn set(&mut self, i: u32, v: bool) {
        if i >= Self::size() {
            panic!("index overflow");
        }
        if v {
            self.0 |= 1 << i;
        } else {
            self.0 &= !(1 << i);
        }
    }

    fn rotate_left(self, n: u32) -> Self {
        Bw64(self.0.rotate_left(n))
    }

    fn rotate_right(self, n: u32) -> Self {
        Bw64(self.0.rotate_right(n))
    }
}

impl Rand for Bw64 {
    fn rand<R: Rng>(rng: &mut R) -> Self {
        Bw64(rng.next_u64())
    }
}

/// The sequence of zeroes and ones, the MSB (most significant bit)
/// appearing on the left.
///
impl Debug for Bw64 {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        let bytes = self.to_bytes();
        for b in bytes {
            try!(f.write_str(&format!("{:08b}", b)));
        }
        Ok(())
    }
}

impl BitAnd for Bw64 {

    type Output = Self;

    fn bitand(self, rhs: Self) -> Self {
        Bw64(self.0 & rhs.0)
    }
}

impl BitOr for Bw64 {

    type Output = Self;

    fn bitor(self, rhs: Self) -> Self {
        Bw64(self.0 | rhs.0)
    }
}

impl BitXor for Bw64 {

    type Output = Self;

    fn bitxor(self, rhs: Self) -> Self {
        Bw64(self.0 ^ rhs.0)
    }
}

impl Not for Bw64 {

    type Output = Self;

    fn not(self) -> Self {
        Bw64(!self.0)
    }
}

impl Shl<u32> for Bw64 {

    type Output = Self;

    fn shl(self, rhs: u32) -> Self {
        if rhs >= Self::size() {
            Self::empty()
        } else {
            Bw64(self.0 << rhs)
        }
    }
}

impl Shr<u32> for Bw64 {

    type Output = Self;

    fn shr(self, rhs: u32) -> Self {
        if rhs >= Self::size() {
            Self::empty()
        } else {
            Bw64(self.0 >> rhs)
        }
    }
}

/// An iterator over the bits.
///
/// Bits are iterated from the least significant one to the most
/// significant one.
///
/// # Examples
///
/// ```
/// use bigwise::{Bigwise, Bw64};
/// let b = Bw64::from_bytes(&[0b11111000]);
/// let mut it = b.into_iter();
/// assert_eq!(Some(false), it.next());
/// assert_eq!(Some(false), it.next());
/// assert_eq!(Some(false), it.next());
/// assert_eq!(Some(true), it.next());
/// assert_eq!(Some(true), it.next());
/// assert_eq!(Some(true), it.next());
/// assert_eq!(Some(true), it.next());
/// assert_eq!(Some(true), it.next());
/// assert_eq!(Some(false), it.next());
/// assert_eq!(Some(false), it.next());
/// assert!(it.take(200).all(|v| v == false));
/// ```
///
impl IntoIterator for Bw64 {
    type Item = bool;
    type IntoIter = BitsIter<Self>;

    fn into_iter(self) -> Self::IntoIter {
        BitsIter::new(self)
    }
}