From f8c8c66f57f4c1f718becd19d6f788538bfb050e Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Sat, 11 Jun 2022 20:38:11 +1000 Subject: [PATCH] Impl new fn `helpers::download_tar_based_and_visit` Signed-off-by: Jiahao XU --- src/helpers.rs | 35 +++++++++++++++++++++++++++++++++- src/helpers/async_extracter.rs | 26 +++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/helpers.rs b/src/helpers.rs index bd2d904f..7670b15b 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -1,3 +1,4 @@ +use std::fmt::Debug; use std::path::{Path, PathBuf}; use cargo_toml::Manifest; @@ -19,6 +20,8 @@ mod ui_thread; pub use ui_thread::UIThread; mod extracter; +pub use extracter::TarEntriesVisitor; + mod readable_rx; /// Load binstall metadata from the crate `Cargo.toml` at the provided path @@ -83,7 +86,7 @@ pub async fn download_and_extract>( /// Download a file from the provided URL and extract part of it to /// the provided path. /// -/// * `filter` - If Some, then it will pass the path of the file to it +/// * `filter` - It will pass the path of the file to it /// and only extract ones which filter returns `true`. pub async fn download_and_extract_with_filter< Filter: FnMut(&Path) -> bool + Send + 'static, @@ -110,6 +113,36 @@ pub async fn download_and_extract_with_filter< Ok(()) } +/// Download a file from the provided URL and extract part of it to +/// the provided path. +/// +/// * `filter` - If Some, then it will pass the path of the file to it +/// and only extract ones which filter returns `true`. +pub async fn download_tar_based_and_visit< + V: TarEntriesVisitor + Debug + Send + 'static, + P: AsRef, +>( + url: Url, + fmt: TarBasedFmt, + path: P, + visitor: V, +) -> Result { + debug!("Downloading from: '{url}'"); + + let resp = create_request(url).await?; + + let path = path.as_ref(); + debug!("Downloading to file: '{}'", path.display()); + + let stream = resp.bytes_stream(); + + let visitor = extract_tar_based_stream_and_visit(stream, path, fmt, visitor).await?; + + debug!("Download OK, written to file: '{}'", path.display()); + + Ok(visitor) +} + /// Fetch install path from environment /// roughly follows pub fn get_install_path>(install_path: Option

) -> Option { diff --git a/src/helpers/async_extracter.rs b/src/helpers/async_extracter.rs index 5a4051ac..cdf8ffea 100644 --- a/src/helpers/async_extracter.rs +++ b/src/helpers/async_extracter.rs @@ -282,3 +282,29 @@ where }) .await } + +pub async fn extract_tar_based_stream_and_visit( + stream: impl Stream> + Unpin, + output: &Path, + fmt: TarBasedFmt, + mut visitor: V, +) -> Result +where + BinstallError: From, +{ + let path = output.to_owned(); + + extract_impl(stream, move |mut rx| { + fs::create_dir_all(path.parent().unwrap())?; + + extract_compressed_from_readable( + ReadableRx::new(&mut rx), + fmt, + &*path, + Some(&mut visitor), + )?; + + Ok(visitor) + }) + .await +}