compact-pro 0.2.0

Read compressed files created by Compact Pro
Documentation
use binrw::BinReaderExt;
use std::{io, rc::Rc};

use crate::{Entry, Error};

pub struct EntryIterator<R> {
    next_offset: u64,
    inner: Rc<R>,
    had_error: bool,
}

impl<R: io::Read + io::Seek> EntryIterator<R> {
    pub(crate) fn try_at(offset: u64, reader: Rc<R>) -> Result<Self, Error> {
        Ok(Self {
            next_offset: offset,
            inner: reader,
            had_error: false,
        })
    }
}

impl<R: io::Read + io::Seek> Iterator for EntryIterator<R> {
    type Item = Result<Entry, Error>;

    fn next(&mut self) -> Option<Self::Item> {
        let inner = unsafe { Rc::get_mut_unchecked(&mut self.inner) };
        inner.seek(io::SeekFrom::Start(self.next_offset)).ok()?;

        if self.had_error {
            return None;
        }

        if inner.stream_position().ok()? == inner.stream_len().ok()? {
            return None;
        }

        let entry: Entry = inner.read_be().ok()?;
        self.next_offset = inner.stream_position().ok()?;

        Some(Ok(entry))
    }
}