git_rs 0.1.0

A (work in progress) pure rust git implementation.
Documentation
use flate2::bufread::ZlibDecoder;
use std::io::prelude::*;
use std;

use crate::pack::internal_type::PackfileType;
use crate::delta::{ OFS_DELTA, REF_DELTA };
use crate::errors::{ Result, ErrorKind };
use crate::id::Id;

pub fn packfile_read<R: BufRead, W: Write>(
    input: &mut R,
    output: &mut W,
    read_bytes: &mut u64
) -> Result<PackfileType> {
    let mut byte = [0u8; 1];
    input.read_exact(&mut byte)?;

    let obj_type = (byte[0] & 0x70) >> 4;
    let mut size = (byte[0] & 0xf) as u64;
    let mut count = 0;
    let mut continuation = byte[0] & 0x80;
    loop {
        if continuation < 1 {
            break
        }

        input.read_exact(&mut byte)?;
        continuation = byte[0] & 0x80;

        size |= ((byte[0] & 0x7f) as u64) << (4 + 7 * count);
        count += 1;
    }

    match obj_type {
        0...4 => {
            let mut deflate_stream = ZlibDecoder::new(input);
            std::io::copy(&mut deflate_stream, output)?;
            *read_bytes = 1 + count + deflate_stream.total_in();
            return Ok(PackfileType::Plain(obj_type));
        },

        OFS_DELTA => {
            input.read_exact(&mut byte)?;
            let mut offset = u64::from(byte[0] & 0x7F);

            while byte[0] & 0x80 > 0 {
                offset += 1;
                offset <<= 7;
                input.read_exact(&mut byte)?;
                offset += u64::from(byte[0] & 0x7F);
                count += 1;
            }

            let mut deflate_stream = ZlibDecoder::new(input);
            let mut instructions = Vec::new();
            deflate_stream.read_to_end(&mut instructions)?;

            *read_bytes = 2 + count + deflate_stream.total_in();
            return Ok(PackfileType::OffsetDelta((offset, instructions)))
        },

        REF_DELTA => {
            let mut ref_bytes = [0u8; 20];
            input.read_exact(&mut ref_bytes)?;
            let id = Id::from(&ref_bytes);

            let mut deflate_stream = ZlibDecoder::new(input);
            let mut instructions = Vec::new();
            deflate_stream.read_to_end(&mut instructions)?;
            *read_bytes = 21 + count + deflate_stream.total_in();
            return Ok(PackfileType::RefDelta((id, instructions)))
        },

        _ => {
            Err(ErrorKind::BadLooseObject.into())
        }
    }
}