use std::path::Path; use std::fs; pub fn extract_zip(zip_path: &Path, extract_to: &Path) -> Result<(), String> { let file = fs::File::open(zip_path).map_err(|e| format!("Failed to open zip {}: {}", zip_path.display(), e))?; let mut archive = zip::ZipArchive::new(file).map_err(|e| format!("Failed to read zip: {}", e))?; for i in 0..archive.len() { let mut file = archive.by_index(i).map_err(|e| format!("Failed to read zip entry: {}", e))?; let outpath = match file.enclosed_name() { Some(path) => extract_to.join(path), None => continue, }; // Skip META-INF if outpath.to_string_lossy().contains("META-INF") { continue; } if file.name().ends_with('/') { fs::create_dir_all(&outpath).map_err(|e| format!("Failed to create dir: {}", e))?; } else { if let Some(p) = outpath.parent() { if !p.exists() { fs::create_dir_all(&p).map_err(|e| format!("Failed to create dir: {}", e))?; } } let mut outfile = fs::File::create(&outpath).map_err(|e| format!("Failed to create file: {}", e))?; std::io::copy(&mut file, &mut outfile).map_err(|e| format!("Failed to copy file: {}", e))?; } } Ok(()) }