anyreader 0.5.0

Efficiently and recursively read archives and compressed streams of data
Documentation
use crate::container::{Container, Items};
use crate::{FileItem, FileKind, SizeHint};
use std::fmt::Debug;
use std::io;
use std::io::Read;
use tar::EntryType;

pub struct TarContainer<T: Read> {
    archive: tar::Archive<T>,
}

impl<T: Read> Debug for TarContainer<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Tar").finish()
    }
}

impl<T: Read> TarContainer<T> {
    pub fn new(reader: T) -> Self {
        let archive = tar::Archive::new(reader);
        Self { archive }
    }
}

impl<T: Read> Container for TarContainer<T> {
    fn items(&mut self) -> io::Result<impl Items> {
        Ok(self.archive.entries()?.map(move |item| {
            let item = item?;
            let kind = match item.header().entry_type() {
                EntryType::Regular => FileKind::File,
                EntryType::Directory => FileKind::Directory,
                _ => FileKind::Other,
            };
            let path = item.path()?.to_path_buf();
            let size_hint = item.header().size().map_or(SizeHint::Unknown, SizeHint::Exact);
            Ok(FileItem {
                path,
                reader: item,
                kind,
                size_hint,
            })
        }))
    }
}