use crate::error::{Result, LateJavaCoreError};
use std::path::Path;
use zip::ZipArchive;
use std::fs::File;
#[derive(Debug, Clone)]
pub struct ArchiveEntry {
pub name: String,
pub data: Vec<u8>,
pub is_directory: bool,
}
pub struct Unzipper {
archive: ZipArchive<File>,
}
impl Unzipper {
pub fn new(archive_path: &str) -> Result<Self> {
let file = File::open(archive_path)?;
let archive = ZipArchive::new(file)?;
Ok(Self { archive })
}
pub fn get_entries(&mut self) -> Result<Vec<ArchiveEntry>> {
let mut entries = Vec::new();
for i in 0..self.archive.len() {
let file = self.archive.by_index(i)?;
let name = file.name().to_string();
let is_directory = file.is_dir();
let data = if !is_directory {
let mut data = Vec::new();
use std::io::Read;
file.read_to_end(&mut data)?;
data
} else {
Vec::new()
};
entries.push(ArchiveEntry {
name,
data,
is_directory,
});
}
Ok(entries)
}
pub fn extract_file(&mut self, file_name: &str) -> Result<Vec<u8>> {
let mut file = self.archive.by_name(file_name)?;
let mut data = Vec::new();
use std::io::Read;
file.read_to_end(&mut data)?;
Ok(data)
}
pub fn extract_to(&mut self, extract_path: &str) -> Result<()> {
for i in 0..self.archive.len() {
let mut file = self.archive.by_index(i)?;
let outpath = Path::new(extract_path).join(file.name());
if file.name().ends_with('/') {
std::fs::create_dir_all(&outpath)?;
} else {
if let Some(p) = outpath.parent() {
if !p.exists() {
std::fs::create_dir_all(p)?;
}
}
let mut outfile = std::fs::File::create(&outpath)?;
use std::io::Read;
std::io::copy(&mut file, &mut outfile)?;
}
}
Ok(())
}
}