mod error;
mod extractor;
mod limits;
pub mod adapter;
mod driver;
pub mod entry;
pub mod policy;
#[cfg(feature = "async")]
mod async_extractor;
#[cfg(feature = "async")]
pub mod r#async {
pub use crate::async_extractor::*;
}
pub use error::Error;
pub use extractor::{ExtractionMode, Extractor, OverwritePolicy, Progress, Report, SymlinkPolicy};
pub use limits::Limits;
#[cfg(feature = "sevenz")]
pub use adapter::SevenZAdapter;
#[cfg(feature = "tar")]
pub use adapter::TarAdapter;
pub use adapter::ZipAdapter;
pub use driver::{Driver, ExtractionReport, OverwriteMode, ValidationMode};
pub use entry::{Entry, EntryInfo, EntryKind};
pub use policy::{Policy, PolicyChain, PolicyConfig, SymlinkBehavior};
pub fn extract<P, R>(destination: P, reader: R) -> Result<Report, Error>
where
P: AsRef<std::path::Path>,
R: std::io::Read + std::io::Seek,
{
Extractor::new_or_create(destination)?.extract(reader)
}
pub fn extract_file<P, F>(destination: P, file_path: F) -> Result<Report, Error>
where
P: AsRef<std::path::Path>,
F: AsRef<std::path::Path>,
{
let file = std::fs::File::open(file_path)?;
let reader = std::io::BufReader::new(file);
Extractor::new_or_create(destination)?.extract(reader)
}
pub fn list_zip_entries<P: AsRef<std::path::Path>>(
path: P,
) -> Result<Vec<entry::EntryInfo>, Error> {
let mut adapter = ZipAdapter::open(path)?;
adapter.entries_metadata()
}
pub fn list_zip<R: std::io::Read + std::io::Seek>(
reader: R,
) -> Result<Vec<entry::EntryInfo>, Error> {
let mut adapter = ZipAdapter::new(reader)?;
adapter.entries_metadata()
}
#[cfg(feature = "tar")]
pub fn list_tar_entries<P: AsRef<std::path::Path>>(
path: P,
) -> Result<Vec<entry::EntryInfo>, Error> {
let file = std::fs::File::open(path)?;
let reader = std::io::BufReader::new(file);
list_tar(reader)
}
#[cfg(feature = "tar")]
pub fn list_tar_gz_entries<P: AsRef<std::path::Path>>(
path: P,
) -> Result<Vec<entry::EntryInfo>, Error> {
let file = std::fs::File::open(path)?;
let reader = std::io::BufReader::new(file);
let decoder = flate2::read::GzDecoder::new(reader);
list_tar(decoder)
}
#[cfg(feature = "tar")]
pub fn list_tar<R: std::io::Read>(reader: R) -> Result<Vec<entry::EntryInfo>, Error> {
let mut entries = Vec::new();
let mut archive = tar::Archive::new(reader);
for entry_result in archive.entries()? {
let entry = entry_result?;
let header = entry.header();
let name = entry.path()?.to_string_lossy().into_owned();
let entry_type = header.entry_type();
let kind = match entry_type {
tar::EntryType::Regular | tar::EntryType::Continuous => EntryKind::File,
tar::EntryType::Directory => EntryKind::Directory,
tar::EntryType::Symlink | tar::EntryType::Link => {
let target = entry
.link_name()?
.map(|p| p.to_string_lossy().into_owned())
.unwrap_or_default();
EntryKind::Symlink { target }
}
other => {
return Err(Error::UnsupportedEntryType {
entry: name,
entry_type: format!("{:?}", other),
});
}
};
entries.push(entry::EntryInfo {
name,
size: header.size()?,
kind,
mode: header.mode().ok(),
});
}
Ok(entries)
}