bigwise 0.4.0

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

/// A type that supports bitwise operations.
///
/// An impl of this trait must declare the number of bits it works with,
/// using the `size` method.
///
/// Note that bitwise operations can be applied only between operands of
/// the exact same type, and not two different types that both implement
/// `Bigwise`.
///
pub trait Bigwise : Rand + Debug + Eq + Copy + Hash + Default + Ord
                    + BitAnd<Output = Self>
                    + BitOr<Output = Self>
                    + BitXor<Output = Self>
                    + Not<Output = Self>
                    + Shl<u32, Output = Self>
                    + Shr<u32, Output = Self>
                    + IntoIterator<Item=bool, IntoIter=BitsIter<Self>>
{

    /// Number of bits stored.
    fn size() -> u32;

    /// A value with all bits set to 0.
    fn empty() -> Self;

    /// A value with all bits set to 1.
    fn full() -> Self;

    /// Creates a value based on raw data.
    ///
    /// The LSB (least significant bit) of the last element of the slice
    /// will become the LSB of the created value.
    ///
    /// If `byte` contains less bits than the type allows, then the MSB
    /// (most significant bits) of the created value will be set to 0. If
    /// `byte` contains more bits than the type allows, then only the last
    /// n elements of the slice will be used to set the content of the
    /// created value (with `n` = `size` / 8).
    ///
    /// # Examples
    ///
    /// ```
    /// use bigwise::{Bigwise, Bw64};
    /// let b = Bw64::from_bytes(&[0b00010000, 0b00000000]);
    /// assert_eq!(true, b.get(12));
    /// ```
    ///
    fn from_bytes(byte: &[u8]) -> Self;

    /// The content of the value as raw bytes.
    ///
    /// The MSB (most significant bit) of the first u8 is the MSB of the
    /// value. The LSB (least significant bit) of the last u8 is the LSB of
    /// the value.
    ///
    /// # Examples
    ///
    /// ```
    /// use bigwise::{Bigwise, Bw64};
    /// let b = Bw64::from_bytes(&[0b11100100, 0b11111000]);
    /// let v = b.to_bytes();
    /// assert_eq!(8, v.len());
    /// assert_eq!(0b00000000, v[0]);
    /// assert_eq!(0b00000000, v[1]);
    /// assert_eq!(0b00000000, v[2]);
    /// assert_eq!(0b00000000, v[3]);
    /// assert_eq!(0b00000000, v[4]);
    /// assert_eq!(0b00000000, v[5]);
    /// assert_eq!(0b11100100, v[6]);
    /// assert_eq!(0b11111000, v[7]);
    /// ```
    ///
    fn to_bytes(self) -> Vec<u8>;

    /// The boolean value of the given bit.
    ///
    /// Bits are indexed from the least significant (index 0) to the most
    /// significant.
    ///
    /// if `i` is outside the capacity of this type, the returned value is
    /// always false (as if the value had an infinite amout of 0 before
    /// the most significant bit).
    ///
    /// # Examples
    ///
    /// ```
    /// use bigwise::{Bigwise, Bw64};
    /// let b = Bw64::from_bytes(&[0b01010101]);
    /// assert_eq!(true, b.get(0));
    /// assert_eq!(false, b.get(1));
    ///
    fn get(self, i: u32) -> bool;

    /// Assigns a boolean value to a given bit.
    ///
    /// Bits are indexed from the least significant (index 0) to the most
    /// significant.
    ///
    /// # Examples
    ///
    /// ```
    /// use bigwise::{Bigwise, Bw64};
    /// let mut b = Bw64::from_bytes(&[0b01010101]);
    /// assert_eq!(true, b.get(4));
    /// b.set(4, false);
    /// assert_eq!(false, b.get(4));
    /// ```
    ///
    /// # Panics
    ///
    /// Panics if `i` >= `size`.
    ///
    fn set(&mut self, i: u32, v: bool);

    /// Rotates all the bits `n` positions to the left.
    ///
    /// The bits that are lost on the MSB (most significant bit) side are
    /// re-inserted on the LSB (least significant bit) side.
    ///
    /// # Examples
    ///
    /// ```
    /// use bigwise::{Bigwise, Bw64};
    /// let b = Bw64::from_bytes(&[0b10100001]);
    /// let shifted = b.rotate_left(63);
    /// assert_eq!(0b01010000, shifted.to_bytes()[7]);
    /// assert_eq!(0b10000000, shifted.to_bytes()[0]);
    /// ```
    ///
    fn rotate_left(self, n: u32) -> Self;

    /// Rotates all the bits `n` positions to the right.
    ///
    /// The bits that are lost on the LSB (least significant bit) side are
    /// re-inserted on the MSB (most significant bit) side.
    ///
    /// # Examples
    ///
    /// ```
    /// use bigwise::{Bigwise, Bw64};
    /// let b = Bw64::from_bytes(&[0b10100001]);
    /// let shifted = b.rotate_right(1);
    /// assert_eq!(0b01010000, shifted.to_bytes()[7]);
    /// assert_eq!(0b10000000, shifted.to_bytes()[0]);
    /// ```
    ///
    fn rotate_right(self, n: u32) -> Self;
}

/// An iterator over the bits.
///
/// Bits are iterated from the least significant one to the most
/// significant one.
///
pub struct BitsIter<T: Bigwise> {
    bw: T,
    idx: u32,
}

impl<T: Bigwise> BitsIter<T> {

    /// Create a new iterator, starting at index 0 (least significant bit)
    pub fn new(bw: T) -> BitsIter<T> {
        BitsIter { bw: bw, idx: 0 }
    }
}

impl<T: Bigwise> Iterator for BitsIter<T> {
    type Item = bool;

    fn next(&mut self) -> Option<Self::Item> {
        if self.idx < T::size() {
            let res = Some(self.bw.get(self.idx));
            self.idx += 1;
            res
        } else {
            None
        }
    }
}