rs-dir2zips2count 0.1.0

Counts items in all zip files in a directory
Documentation
use std::fs::File;
use std::io;

use std::path::Path;
use std::path::PathBuf;

use io::Read;
use io::Seek;

use zip::ZipArchive;

pub fn zip2len<R>(z: &ZipArchive<R>) -> usize
where
    R: Read + Seek,
{
    z.len()
}

pub fn zipnames2total_item_count<I, P>(mut zipnames: I) -> Result<usize, io::Error>
where
    I: Iterator<Item = Result<P, io::Error>>,
    P: AsRef<Path>,
{
    zipnames.try_fold(0, |state, next| {
        let arp = next?;
        let f: File = File::open(arp)?;
        let z: ZipArchive<_> = ZipArchive::new(f)?;
        let subtot: usize = zip2len(&z);
        Ok(state + subtot)
    })
}

pub fn dir2zipnames<P, Z>(
    dir: P,
    is_zip: Z,
) -> Result<impl Iterator<Item = Result<PathBuf, io::Error>>, io::Error>
where
    P: AsRef<Path>,
    Z: Fn(&Path) -> bool,
{
    let dirents = std::fs::read_dir(dir)?;
    Ok(dirents.filter_map(move |rdirent| match rdirent {
        Err(e) => Some(Err(e)),
        Ok(dirent) => {
            let p: PathBuf = dirent.path();
            let zfile: bool = is_zip(&p);
            zfile.then_some(Ok(p))
        }
    }))
}

pub fn is_zip_simple(p: &Path) -> bool {
    let opt_os_str: Option<&_> = p.extension();
    match opt_os_str {
        None => false,
        Some(os_str) => os_str.eq("zip"),
    }
}

/// Counts all items in the all zip files found in the specified dir.
pub fn dir2zipnames2total_count<P, Z>(dir: P, is_zip: Z) -> Result<usize, io::Error>
where
    P: AsRef<Path>,
    Z: Fn(&Path) -> bool,
{
    let zip_paths = dir2zipnames(dir, is_zip)?;
    zipnames2total_item_count(zip_paths)
}

/// Counts all items in the all zip files using the simple zip name checker.
pub fn dir2zipnames2total_count_default<P>(dir: P) -> Result<usize, io::Error>
where
    P: AsRef<Path>,
{
    dir2zipnames2total_count(dir, is_zip_simple)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_is_zip_simple() {
        assert!(is_zip_simple(Path::new("foo.zip")));
        assert!(!is_zip_simple(Path::new("baz.txt")));
    }
}