pacenotes_installer\zip/
extraction.rs1#[derive(Clone, Debug, PartialEq, Eq)]
3pub struct FileEntry {
4 pub path: String,
6 pub size: u64,
8}
9
10pub fn entries(zip_bytes: &[u8]) -> Result<Vec<FileEntry>, super::ZipError> {
13 Ok(super::central_directory::read(zip_bytes)?
14 .into_iter()
15 .filter(|entry| !entry.is_dir)
16 .map(|entry| FileEntry {
17 path: entry.path,
18 size: entry.uncompressed as u64,
19 })
20 .collect())
21}
22
23pub fn entry_paths(zip_bytes: &[u8]) -> Result<Vec<String>, super::ZipError> {
24 Ok(entries(zip_bytes)?
25 .into_iter()
26 .map(|entry| entry.path)
27 .collect())
28}
29
30pub fn read_entry(zip_bytes: &[u8], path: &str) -> Result<Vec<u8>, super::ZipError> {
33 super::Archive::open(zip_bytes)?.read(path)
34}
35
36pub fn extract(
42 zip_bytes: &[u8],
43 dest_dir: &std::path::Path,
44) -> Result<Vec<String>, super::ZipError> {
45 let entries = super::central_directory::read(zip_bytes)?;
46 create_dir(dest_dir)?;
47
48 let mut written = Vec::new();
49 for entry in &entries {
50 let target = crate::relative_path::join(dest_dir, &entry.path);
51 if entry.is_dir {
52 create_dir(&target)?;
53 continue;
54 }
55 if let Some(parent) = target.parent() {
57 create_dir(parent)?;
58 }
59 let data = super::entry_data::read(zip_bytes, entry)?;
60 std::fs::write(&target, &data)
61 .map_err(|e| super::ZipError::new(format!("cannot write {}: {e}", target.display())))?;
62 written.push(entry.path.clone());
63 }
64 Ok(written)
65}
66
67fn create_dir(path: &std::path::Path) -> Result<(), super::ZipError> {
68 std::fs::create_dir_all(path)
69 .map_err(|e| super::ZipError::new(format!("cannot create {}: {e}", path.display())))
70}