chapter_tgz/independent.rs
1use std::io::{Cursor, Read, Result, Seek};
2
3/// Trait bound enabling `TgzReader::independent_read_chapter`.
4///
5/// See the example code on [`independent_read_chapter`].
6///
7/// [`independent_read_chapter`]: crate::TgzReader::independent_read_chapter
8///
9/// # Example
10///
11/// A reader that increments an [Indicatif] progress bar as bytes are read.
12///
13/// [Indicatif]: https://crates.io/crates/indicatif
14///
15/// ```
16/// use chapter_tgz::IndependentRead;
17/// use indicatif::ProgressBar;
18/// use std::io::{self, Read, Seek, SeekFrom};
19///
20/// pub struct ProgressRead<'a, R> {
21/// inner: R,
22/// progress: &'a ProgressBar,
23/// }
24///
25/// impl<R: Read> Read for ProgressRead<'_, R> {
26/// fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
27/// let n = self.inner.read(buf)?;
28/// self.progress.inc(n as u64);
29/// Ok(n)
30/// }
31/// }
32///
33/// impl<R: Seek> Seek for ProgressRead<'_, R> {
34/// fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
35/// self.inner.seek(pos)
36/// }
37/// }
38///
39/// impl<R: IndependentRead> IndependentRead for ProgressRead<'_, R> {
40/// fn independent_clone(&self) -> io::Result<Self> {
41/// Ok(ProgressRead {
42/// inner: self.inner.independent_clone()?,
43/// progress: self.progress,
44/// })
45/// }
46/// }
47/// ```
48pub trait IndependentRead: Read + Seek + Sized {
49 /// Produce a clone of self in such a way that `read` and `seek` operations
50 /// on the clone do not affect the position of reads from the original.
51 fn independent_clone(&self) -> Result<Self>;
52}
53
54impl<T> IndependentRead for Cursor<T>
55where
56 T: AsRef<[u8]> + Clone,
57{
58 fn independent_clone(&self) -> Result<Self> {
59 Ok(self.clone())
60 }
61}