bytebuilder 0.3.0

A simple binary serializer/deserializer
Documentation
use crate::traits::{Byteable, Reader};

pub struct BitReader<'a> {
    pub bytes: &'a [u8],
    pub bit_pos: usize,
    pub byte_pos: usize,
}

impl<'a> BitReader<'a> {
    pub fn new(bytes: &'a [u8]) -> Self {
        BitReader {
            bytes,
            bit_pos: 0,
            byte_pos: 0,
        }
    }

    pub fn read_bit(&mut self) -> Option<bool> {
        if self.byte_pos < self.bytes.len() {
            let byte = self.bytes[self.byte_pos];
            let bit = (byte >> (7 - self.bit_pos)) & 1;
            self.bit_pos += 1;

            if self.bit_pos == 8 {
                self.bit_pos = 0;
                self.byte_pos += 1;
            }

            Some(bit != 0)
        } else {
            None
        }
    }
}

impl<'a> Reader for BitReader<'a> {
    fn read_u8(&mut self) -> Option<u8> {
        if self.remaining() >= 8 {
            let mut value = 0;
            for i in 0..8 {
                if let Some(bit) = self.read_bit() {
                    if bit {
                        value |= 1 << (7 - i);
                    }
                } else {
                    return None;
                }
            }
            Some(value)
        } else {
            None
        }
    }

    fn read<T: Byteable>(&mut self) -> Option<T> {
        T::from_bytes(self)
    }

    fn remaining(&self) -> usize {
        let total_bits = self.bytes.len() * 8;
        total_bits - (self.byte_pos * 8 + self.bit_pos)
    }

    fn reset(&mut self) {
        self.bit_pos = 0;
        self.byte_pos = 0;
    }

    fn skip(&mut self, len: usize) -> bool {
        let bits_to_skip = len * 8;
        if bits_to_skip <= self.remaining() {
            self.byte_pos += bits_to_skip / 8;
            self.bit_pos += bits_to_skip % 8;
            if self.bit_pos >= 8 {
                self.byte_pos += 1;
                self.bit_pos -= 8;
            }
            true
        } else {
            false
        }
    }
}