Skip to main content

rs_dir2zips2count/
lib.rs

1use std::fs::File;
2use std::io;
3
4use std::path::Path;
5use std::path::PathBuf;
6
7use io::Read;
8use io::Seek;
9
10use zip::ZipArchive;
11
12pub fn zip2len<R>(z: &ZipArchive<R>) -> usize
13where
14    R: Read + Seek,
15{
16    z.len()
17}
18
19pub fn zipnames2total_item_count<I, P>(mut zipnames: I) -> Result<usize, io::Error>
20where
21    I: Iterator<Item = Result<P, io::Error>>,
22    P: AsRef<Path>,
23{
24    zipnames.try_fold(0, |state, next| {
25        let arp = next?;
26        let f: File = File::open(arp)?;
27        let z: ZipArchive<_> = ZipArchive::new(f)?;
28        let subtot: usize = zip2len(&z);
29        Ok(state + subtot)
30    })
31}
32
33pub fn dir2zipnames<P, Z>(
34    dir: P,
35    is_zip: Z,
36) -> Result<impl Iterator<Item = Result<PathBuf, io::Error>>, io::Error>
37where
38    P: AsRef<Path>,
39    Z: Fn(&Path) -> bool,
40{
41    let dirents = std::fs::read_dir(dir)?;
42    Ok(dirents.filter_map(move |rdirent| match rdirent {
43        Err(e) => Some(Err(e)),
44        Ok(dirent) => {
45            let p: PathBuf = dirent.path();
46            let zfile: bool = is_zip(&p);
47            zfile.then_some(Ok(p))
48        }
49    }))
50}
51
52pub fn is_zip_simple(p: &Path) -> bool {
53    let opt_os_str: Option<&_> = p.extension();
54    match opt_os_str {
55        None => false,
56        Some(os_str) => os_str.eq("zip"),
57    }
58}
59
60/// Counts all items in the all zip files found in the specified dir.
61pub fn dir2zipnames2total_count<P, Z>(dir: P, is_zip: Z) -> Result<usize, io::Error>
62where
63    P: AsRef<Path>,
64    Z: Fn(&Path) -> bool,
65{
66    let zip_paths = dir2zipnames(dir, is_zip)?;
67    zipnames2total_item_count(zip_paths)
68}
69
70/// Counts all items in the all zip files using the simple zip name checker.
71pub fn dir2zipnames2total_count_default<P>(dir: P) -> Result<usize, io::Error>
72where
73    P: AsRef<Path>,
74{
75    dir2zipnames2total_count(dir, is_zip_simple)
76}
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81
82    #[test]
83    fn test_is_zip_simple() {
84        assert!(is_zip_simple(Path::new("foo.zip")));
85        assert!(!is_zip_simple(Path::new("baz.txt")));
86    }
87}