From 9584c8d35e7c69939935b7b11e3befe0a50e5a86 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Mon, 13 Jun 2022 01:06:12 +1000 Subject: [PATCH] Refactor: Extract `create_tar_decoder` from `extract_compressed_from_readable`. Signed-off-by: Jiahao XU --- src/helpers/extracter.rs | 70 +++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/src/helpers/extracter.rs b/src/helpers/extracter.rs index cbf65802..5994882f 100644 --- a/src/helpers/extracter.rs +++ b/src/helpers/extracter.rs @@ -32,9 +32,10 @@ pub(super) enum Op<'a, V: TarEntriesVisitor> { /// * `f` - If Some, then this function will pass /// the entries of the `dat` to it and let it decides /// what to do with the tar. -fn untar(dat: R, op: Op<'_, V>) -> Result<(), BinstallError> { - let mut tar = Archive::new(dat); - +fn untar( + mut tar: Archive, + op: Op<'_, V>, +) -> Result<(), BinstallError> { match op { Op::Visit(mut visitor) => { debug!("Untaring with callback"); @@ -52,6 +53,28 @@ fn untar(dat: R, op: Op<'_, V>) -> Result<(), Bin Ok(()) } +pub(super) fn create_tar_decoder( + dat: impl BufRead + 'static, + fmt: TarBasedFmt, +) -> Result>, BinstallError> { + use TarBasedFmt::*; + + let r: Box = match fmt { + Tar => Box::new(dat), + Tgz => Box::new(GzDecoder::new(dat)), + Txz => Box::new(XzDecoder::new(dat)), + Tzstd => { + // The error can only come from raw::Decoder::with_dictionary + // as of zstd 0.10.2 and 0.11.2, which is specified + // as &[] by ZstdDecoder::new, thus ZstdDecoder::new + // should not return any error. + Box::new(ZstdDecoder::with_buffer(dat)?) + } + }; + + Ok(Archive::new(r)) +} + /// Extract files from the specified source onto the specified path. /// /// * `fmt` - must not be `PkgFmt::Bin` or `PkgFmt::Zip`. @@ -59,54 +82,21 @@ fn untar(dat: R, op: Op<'_, V>) -> Result<(), Bin /// and only extract ones which filter returns `true`. /// Note that this is a best-effort and it only works when `fmt` /// is not `PkgFmt::Bin` or `PkgFmt::Zip`. -pub(super) fn extract_compressed_from_readable( +pub(super) fn extract_compressed_from_readable( dat: R, fmt: TarBasedFmt, op: Op<'_, V>, ) -> Result<(), BinstallError> { - use TarBasedFmt::*; - let msg = if let Op::UnpackToPath(path) = op { format!("destination: {path:#?}") } else { "process in-memory".to_string() }; - match fmt { - Tar => { - // Extract to install dir - debug!("Extracting from tar archive: {msg}"); + debug!("Extracting from {fmt} archive: {msg}"); - untar(dat, op)? - } - Tgz => { - // Extract to install dir - debug!("Decompressing from tgz archive: {msg}"); - - let tar = GzDecoder::new(dat); - untar(tar, op)?; - } - Txz => { - // Extract to install dir - debug!("Decompressing from txz archive: {msg}"); - - let tar = XzDecoder::new(dat); - untar(tar, op)?; - } - Tzstd => { - // Extract to install dir - debug!("Decompressing from tzstd archive: {msg}"); - - // The error can only come from raw::Decoder::with_dictionary - // as of zstd 0.10.2 and 0.11.2, which is specified - // as &[] by ZstdDecoder::new, thus ZstdDecoder::new - // should not return any error. - let tar = ZstdDecoder::with_buffer(dat)?; - untar(tar, op)?; - } - }; - - Ok(()) + let tar = create_tar_decoder(dat, fmt)?; + untar(tar, op) } pub(super) fn unzip(dat: File, dst: &Path) -> Result<(), BinstallError> {