stream_buffer 0.2.0

A stream buffer library for Rust
Documentation
use super::buf::{StreamBuffer, ByteStreamBuf, StreamBuffer2, };
use super::constants::{ZERO_BYTE, INCREMENT};
use super::types::{FileLike, BufResult,IntoStream, IterStream};
use super::utils::*;
use std::io::{Read, SeekFrom};
use std::convert::{TryInto, Into};


pub enum Location {
    BeforeIndex,
    Bisected,
    AtIndex,
    AfterIndex,
}

pub trait ChunkLocation {
    fn _chunk_location(&self, offset: usize, size: usize) -> Location;
}

pub trait ChunkRead<T> {
    fn _chunk_before_index(&mut self, offset: usize, size: usize) -> T;
    fn _chunk_bisected_by_index(&mut self,  offset: usize, size: usize) -> T;
    fn _chunk_at_index(&mut self, size: usize) -> T;
    fn _chunk_after_index(&mut self, offset: usize, size: usize) -> T;
}

impl<T, F: FileLike> ChunkLocation for StreamBuffer<T ,F> {
    fn _chunk_location(&self, offset: usize, size: usize) -> Location {
        let end = offset + size;

        if offset < self.index && end <= self.index {
            Location::BeforeIndex
        } else if offset < self.index && self.index < end {
            Location::Bisected
        } else if offset == self.index {
            Location::AtIndex
        } else {
            Location::AfterIndex
        }
    }
}

impl<T: IterStream<S>, S, F: FileLike> ChunkLocation for StreamBuffer2<T, S, F> {
    fn _chunk_location(&self, offset: usize, size: usize) -> Location {
        let end = offset + size;

        if offset < self.index && end <= self.index {
            Location::BeforeIndex
        } else if offset < self.index && self.index < end {
            Location::Bisected
        } else if offset == self.index {
            Location::AtIndex
        } else {
            Location::AfterIndex
        }
    }
}

impl<F: FileLike> ChunkRead<BufResult> for ByteStreamBuf<F> {
    fn _chunk_before_index(&mut self, offset: usize, size: usize) -> BufResult {
        let seek_offset = SeekFrom::Start(offset as u64);
        let mut buf = sized_vec(size, ZERO_BYTE);

        self.file.seek(seek_offset)?;
        self.file.read(&mut buf)?;

        Ok(buf)
    }

    fn _chunk_bisected_by_index(&mut self, offset: usize, size: usize) -> BufResult {
        let existing_size = self.index - offset;
        let mut buf = 
            self._chunk_before_index(offset, existing_size)?;
        
        let new_size = size - buf.len();
        let new_buf = self._chunk_at_index(new_size)?;
        buf.extend(new_buf);

        Ok(buf)
    }

    fn _chunk_at_index(&mut self, size: usize) -> BufResult {
        let seek_offset = SeekFrom::Start(self.index as u64);
        self.file.seek(seek_offset)?;

        let mut buf = no_capacity_vec();
        
        while let Some(Ok(byte)) = self.stream.next() {
            let bytes = &[byte];
            self.file.write(bytes)?;
            self.index += INCREMENT;

            buf.extend_one(byte);

            if buf.len() >= size {
                buf.truncate(size);
                break;
            }
        }

        Ok(buf)
    }

    fn _chunk_after_index(&mut self, offset: usize, size: usize) -> BufResult {
        let seek_index = SeekFrom::Start(self.index as u64);
        self.file.seek(seek_index)?;

        let mut buf = no_capacity_vec();

        while let Some(Ok(byte)) = self.stream.next()  {
            let bytes = &[byte];
            self.file.write(bytes)?;
            self.index += INCREMENT;

            if self.index >= offset {
                buf.extend_one(byte);
            }

            if buf.len() >= size {
                buf.truncate(size);
                break;
            }
        }

        Ok(buf)
    }
}

impl<T: IterStream<BufResult>, F: FileLike> ChunkRead<BufResult> for StreamBuffer2<T, BufResult, F> {
    fn _chunk_before_index(&mut self, offset: usize, size: usize) -> BufResult {
        let seek_offset = SeekFrom::Start(offset as u64);
        let mut buf = sized_vec(size, ZERO_BYTE);

        self.file.seek(seek_offset)?;
        self.file.read(&mut buf)?;

        Ok(buf)
    }

    fn _chunk_bisected_by_index(&mut self, offset: usize, size: usize) -> BufResult {
        let existing_size = self.index - offset;
        let mut buf = 
            self._chunk_before_index(offset, existing_size)?;
        
        let new_size = size - buf.len();
        let new_buf = self._chunk_at_index(new_size)?;
        buf.extend(new_buf);

        Ok(buf)
    }

    fn _chunk_at_index(&mut self, size: usize) -> BufResult {
        let seek_offset = SeekFrom::Start(self.index as u64);
        self.file.seek(seek_offset)?;

        let mut buf = no_capacity_vec();

        for chunk in self.stream.by_ref() {
            let bytes: Vec<u8> = chunk?;

            self.file.write(&bytes)?;
            self.index += bytes.len();

            buf.extend(bytes);

            if buf.len() >= size {
                buf.truncate(size);
                break;
            }
        }


        Ok(buf)
    }

    fn _chunk_after_index(&mut self, offset: usize, size: usize) -> BufResult {
        let seek_index = SeekFrom::Start(self.index as u64);
        self.file.seek(seek_index)?;

        let mut buf = no_capacity_vec();

        for chunk in self.stream.by_ref() {
            let bytes: Vec<u8> = chunk?;

            self.file.write(&bytes)?;
            self.index += bytes.len();

            if self.index >= offset {
                buf.extend(bytes);
            }

            if buf.len() >= size {
                buf.truncate(size);
                break;
            }
        }

        Ok(buf)
    }
}