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))
}
}