use crate::Result;
use std::path::Path;
use tempfile::TempDir;
use tokio::io::AsyncRead;
use url::Url;
pub async fn extract_tar_archive_from_reader<R: AsyncRead + Unpin + Send + 'static>(
reader: R,
) -> Result<TempDir> {
let bridge = tokio_util::io::SyncIoBridge::new(reader);
let temp_dir = TempDir::new()?;
let path = temp_dir.path().to_owned();
tokio::task::spawn_blocking(move || {
let mut archive = tar::Archive::new(bridge);
println!("Tar archive contents extracing to {}:", path.display());
for result in archive.entries()? {
let mut entry = result?;
let entry_path = entry.path()?.to_path_buf();
println!(" {} ({} bytes)", entry_path.display(), entry.size());
assert!(!path.join(&entry_path).exists());
assert!(entry.unpack_in(&path)?, "unpack_in returned false");
assert!(path.join(&entry_path).exists());
}
Result::<_>::Ok(())
})
.await??;
Ok(temp_dir)
}
pub async fn extract_tar_archive_from_s3_url(
client: &aws_sdk_s3::Client,
url: &Url,
) -> Result<TempDir> {
let bucket = url.host().unwrap().to_string();
let key = url.path().strip_prefix('/').unwrap();
let response = client.get_object().bucket(bucket).key(key).send().await?;
let bytestream = response.body;
let reader = bytestream.into_async_read();
extract_tar_archive_from_reader(reader).await
}
pub async fn extract_tar_archive_from_file(path: &Path) -> Result<TempDir> {
let file = tokio::fs::File::open(path).await?;
extract_tar_archive_from_reader(file).await
}