chapter-tgz 0.1.0

Specially crafted .tar.gz with embedded chapter boundary information
Documentation
use std::io::{Cursor, Read, Result, Seek};

/// Trait bound enabling `TgzReader::independent_read_chapter`.
///
/// See the example code on [`independent_read_chapter`].
///
/// [`independent_read_chapter`]: crate::TgzReader::independent_read_chapter
///
/// # Example
///
/// A reader that increments an [Indicatif] progress bar as bytes are read.
///
/// [Indicatif]: https://crates.io/crates/indicatif
///
/// ```
/// use chapter_tgz::IndependentRead;
/// use indicatif::ProgressBar;
/// use std::io::{self, Read, Seek, SeekFrom};
///
/// pub struct ProgressRead<'a, R> {
///     inner: R,
///     progress: &'a ProgressBar,
/// }
///
/// impl<R: Read> Read for ProgressRead<'_, R> {
///     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
///         let n = self.inner.read(buf)?;
///         self.progress.inc(n as u64);
///         Ok(n)
///     }
/// }
///
/// impl<R: Seek> Seek for ProgressRead<'_, R> {
///     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
///         self.inner.seek(pos)
///     }
/// }
///
/// impl<R: IndependentRead> IndependentRead for ProgressRead<'_, R> {
///     fn independent_clone(&self) -> io::Result<Self> {
///         Ok(ProgressRead {
///             inner: self.inner.independent_clone()?,
///             progress: self.progress,
///         })
///     }
/// }
/// ```
pub trait IndependentRead: Read + Seek + Sized {
    /// Produce a clone of self in such a way that `read` and `seek` operations
    /// on the clone do not affect the position of reads from the original.
    fn independent_clone(&self) -> Result<Self>;
}

impl<T> IndependentRead for Cursor<T>
where
    T: AsRef<[u8]> + Clone,
{
    fn independent_clone(&self) -> Result<Self> {
        Ok(self.clone())
    }
}