lz-string 0.1.1

implementation of lz-string decompression
Documentation
use std::iter::Map;
use std::slice::Iter;

pub struct RevBitReader<I> {
    bytes: I,
    byte: Option<u8>,
    bit_idx: u8,
}

impl<I> RevBitReader<I> {
    pub fn from_iter(bytes: I) -> Self {
        RevBitReader {
            bytes,
            byte: None,
            bit_idx: 7,
        }
    }
}

#[derive(Debug, PartialEq)]
pub struct NoError;
type MapFn = fn(&u8) -> Result<u8, NoError>;
type WrappedIter<'a> = Map<Iter<'a, u8>, MapFn>;

impl<'a> RevBitReader<WrappedIter<'a>> {
    pub fn from_bytes(bytes: &'a [u8]) -> Self {
        let bytes = bytes.iter().map((|b| Ok(*b)) as MapFn);

        RevBitReader {
            bytes,
            byte: None,
            bit_idx: 7,
        }
    }
}

impl<I, E> RevBitReader<I>
where
    I: Iterator<Item = Result<u8, E>>,
{
    /// Read the n next bits in *reverse order* and return them as a u64. If more
    /// than 64 bits are requested, only the last 64 read bits will be returned.
    /// None is returned when there is no more data to read.
    ///
    /// Reverse order means that taking 2 bits out of `0b10` will return `1`
    /// instead of `2`.
    pub fn take(&mut self, n: u8) -> Option<Result<u64, E>> {
        let mut res = 0u64;

        if self.byte.is_none() {
            nested_try!(self.next()?);
        }

        let mut i = 0;
        while i < n && self.byte.is_some() {
            let mask = 1u64 << self.bit_idx;
            let masked = (self.byte? as u64) & mask;
            let bit = (masked >> self.bit_idx) << i;

            res |= bit;
            i += 1;

            if self.bit_idx == 0 {
                self.bit_idx = 7;
                if let Some(Err(e)) = self.next() {
                    return Some(Err(e));
                }
            } else {
                self.bit_idx -= 1;
            }
        }

        Some(Ok(res))
    }

    fn next(&mut self) -> Option<Result<u8, E>> {
        self.byte = None;
        let byte = nested_try!(self.bytes.next()?);
        self.byte = Some(byte);
        Some(Ok(byte))
    }
}

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

    #[test]
    fn empty() {
        let data = b"";
        let mut reader = RevBitReader::from_bytes(data);

        assert_eq!(reader.take(1), None);
    }

    #[test]
    fn single_byte() {
        let data = &[0x88];
        let mut reader = RevBitReader::from_bytes(data);

        assert_eq!(reader.take(5), Some(Ok(0x11)));
        assert_eq!(reader.take(5), Some(Ok(0x00)));
        assert_eq!(reader.take(5), None);
    }

    #[test]
    fn multiple_bytes() {
        let data = &[0x7E, 0x87];
        let mut reader = RevBitReader::from_bytes(data);

        assert_eq!(reader.take(6), Some(Ok(0x03E)));
        assert_eq!(reader.take(9), Some(Ok(0x185)));
        assert_eq!(reader.take(5), Some(Ok(0x001)));
        assert_eq!(reader.take(2), None);
    }

    #[test]
    fn invalid() {
        #[derive(Debug, PartialEq)]
        struct Error;

        struct InvalidIterator;

        impl Iterator for InvalidIterator {
            type Item = Result<u8, Error>;
            fn next(&mut self) -> Option<Self::Item> {
                Some(Err(Error))
            }
        }

        let iterator = InvalidIterator;
        let mut reader = RevBitReader::from_iter(iterator);

        assert_eq!(reader.take(1), Some(Err(Error)));
    }
}