stream_unzip/
lib.rs

1mod error;
2pub use self::error::*;
3mod reader;
4pub use reader::*;
5mod iterator;
6pub use iterator::*;
7
8#[cfg(test)]
9mod tests {
10    use tokio::io::AsyncReadExt;
11
12    use std::{
13        fs::File,
14        io::Read,
15        path::{Path, PathBuf},
16    };
17
18    use super::*;
19
20    async fn test_zip(path: &Path, buffer_size: usize) -> anyhow::Result<()> {
21        println!("Buffer size: {}", buffer_size);
22        let f = std::fs::File::open(path).unwrap();
23        let f2 = std::fs::File::open(path).unwrap();
24        let mut expected = zip::ZipArchive::new(f2).unwrap();
25        let mut f = tokio::fs::File::from_std(f);
26        let mut buff: [u8; 10000] = [0; 10000];
27        let mut zip_reader = ZipReader::default();
28        while let Ok(num) = f.read(&mut buff).await {
29            if num == 0 {
30                break;
31            }
32            let mut left_to_read = num;
33            let mut last = 0;
34            while left_to_read > 0 {
35                let to_read = if left_to_read <= buffer_size {
36                    left_to_read
37                } else {
38                    buffer_size
39                };
40                zip_reader.update(buff[last..(last + to_read)].to_vec().into());
41                last += to_read;
42                left_to_read -= to_read;
43            }
44        }
45        zip_reader.finish();
46        println!("found {} zip entries", zip_reader.entries().len());
47        let expanded = zip_reader
48            .drain_entries()
49            .into_iter()
50            .map(|e| e.inflate())
51            .collect::<Vec<_>>();
52
53        assert!(!expanded.is_empty());
54        assert_eq!(expanded.len(), expected.len());
55        for entry in expanded {
56            let entry = entry?;
57            // println!("File: {:?}", entry.name());
58            // println!("File size: {:?}", entry.uncompressed_size());
59            // println!("File compressed size: {:?}", entry.compressed_size());
60            let mut expected_entry = expected.by_name(entry.name()).unwrap();
61            assert_eq!(expected_entry.size(), entry.uncompressed_size() as _);
62            let mut expected_bytes = Vec::new();
63            expected_bytes.resize(expected_entry.size() as _, 0);
64            expected_entry.read_exact(&mut expected_bytes).unwrap();
65            assert_eq!(expected_bytes, entry.data().to_vec());
66        }
67        Ok(())
68    }
69
70    #[tokio::test]
71    async fn test_async() -> anyhow::Result<()> {
72        let mut files =
73            std::fs::read_dir(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("testdata")).unwrap();
74
75        while let Some(Ok(file)) = files.next() {
76            if file.path().extension() != Some("zip".as_ref()) {
77                println!("    skipping {}", file.path().to_string_lossy());
78                continue;
79            }
80            println!("--> testing {}", file.path().to_string_lossy());
81            test_zip(&file.path(), 10).await?;
82            test_zip(&file.path(), 300).await?;
83            test_zip(&file.path(), 1024).await?;
84            test_zip(&file.path(), 1024 * 1024).await?;
85        }
86        Ok(())
87    }
88
89    #[test]
90    fn test_iter() {
91        let file = std::fs::File::open(
92            PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("testdata/readme.zip"),
93        )
94        .unwrap();
95        let zip: ZipIterator<File, 32> = file.into();
96
97        let mut entries = Vec::new();
98        for entry in zip {
99            entries.push(entry);
100        }
101
102        assert_eq!(1, entries.len());
103    }
104}