From db0bc8a7d9f5c76854f6c83bb6317163d5764ed2 Mon Sep 17 00:00:00 2001 From: misilelab Date: Thu, 11 May 2023 20:28:05 +0900 Subject: [PATCH] impl except test --- src/archive/mod.rs | 1 + src/archive/sevenz.rs | 40 ++++++++++++++++++++++++++++++++++++++ src/commands/compress.rs | 24 +---------------------- src/commands/decompress.rs | 16 ++++++++------- src/commands/list.rs | 9 ++++++++- src/utils/fs.rs | 5 +++++ 6 files changed, 64 insertions(+), 31 deletions(-) create mode 100644 src/archive/sevenz.rs diff --git a/src/archive/mod.rs b/src/archive/mod.rs index 428f3cb..077d16b 100644 --- a/src/archive/mod.rs +++ b/src/archive/mod.rs @@ -1,5 +1,6 @@ //! Archive compression algorithms pub mod rar; +pub mod sevenz; pub mod tar; pub mod zip; diff --git a/src/archive/sevenz.rs b/src/archive/sevenz.rs new file mode 100644 index 0000000..effae79 --- /dev/null +++ b/src/archive/sevenz.rs @@ -0,0 +1,40 @@ +//! SevenZip archive format compress function +use std::{ + env::current_dir, + path::{Path, PathBuf}, +}; + +pub fn compress_sevenz(files: Vec, output_path: &Path) -> crate::Result { + let mut writer = sevenz_rust::SevenZWriter::create(output_path).map_err(crate::Error::SevenzipError)?; + + for filep in files.iter() { + writer + .push_archive_entry::( + sevenz_rust::SevenZWriter::::create_archive_entry( + filep, + filep + .strip_prefix(current_dir()?) + .expect("StripPrefix Failed") + .as_os_str() + .to_str() + .unwrap() + .to_string(), + ), + None, + ) + .map_err(crate::Error::SevenzipError)?; + } + + writer.finish()?; + Ok(true) +} + +pub fn decompress_sevenz(input_file_path: &Path, output_path: &Path) -> crate::Result { + let mut count: usize = 0; + sevenz_rust::decompress_file_with_extract_fn(input_file_path, output_path, |entry, reader, dest| { + count += 1; + sevenz_rust::default_entry_extract_fn(entry, reader, dest) + }) + .map_err(crate::Error::SevenzipError)?; + Ok(count) +} diff --git a/src/commands/compress.rs b/src/commands/compress.rs index 4ecf82c..bd2a91b 100644 --- a/src/commands/compress.rs +++ b/src/commands/compress.rs @@ -1,5 +1,4 @@ use std::{ - env::current_dir, io::{self, BufWriter, Cursor, Seek, Write}, path::{Path, PathBuf}, }; @@ -128,28 +127,7 @@ pub fn compress_files( return Ok(false); }, SevenZip => { - let mut writer = - sevenz_rust::SevenZWriter::create(output_path).map_err(|e| crate::Error::SevenzipError(e))?; - - for filep in files.iter() { - writer - .push_archive_entry::( - sevenz_rust::SevenZWriter::::create_archive_entry( - filep, - filep - .strip_prefix(current_dir()?) - .expect("StripPrefix Failed") - .as_os_str() - .to_str() - .unwrap() - .to_string(), - ), - None, - ) - .map_err(|e| crate::Error::SevenzipError(e))?; - } - - writer.finish()?; + archive::sevenz::compress_sevenz(files, output_path)?; } } diff --git a/src/commands/decompress.rs b/src/commands/decompress.rs index 675c549..9f70433 100644 --- a/src/commands/decompress.rs +++ b/src/commands/decompress.rs @@ -165,14 +165,16 @@ pub fn decompress_file( } }, SevenZip => { - let mut count = 0; - sevenz_rust::decompress_file_with_extract_fn(input_file_path, output_dir, - |entry, reader, dest| { - count += 1; - sevenz_rust::default_entry_extract_fn(entry, reader, dest) + if let ControlFlow::Continue(files) = smart_unpack( + |output_dir| crate::archive::sevenz::decompress_sevenz(input_file_path, output_dir), + output_dir, + &output_file_path, + question_policy, + )? { + files + } else { + return Ok(()); } - ).map_err(|x| crate::Error::SevenzipError(x))?; - count } }; diff --git a/src/commands/list.rs b/src/commands/list.rs index 9d21e36..cbf20a6 100644 --- a/src/commands/list.rs +++ b/src/commands/list.rs @@ -88,6 +88,13 @@ pub fn list_archive_contents( } }, SevenZip => { + if formats.len() > 1 { + warn_user_about_loading_zip_in_memory(); + if !user_wants_to_continue(archive_path, question_policy, QuestionAction::Decompression)? { + return Ok(()); + } + } + let mut a = Vec::new(); sevenz_rust::decompress_file_with_extract_fn(archive_path, ".", |entry, _, _| { @@ -97,7 +104,7 @@ pub fn list_archive_contents( })); Ok(true) }) - .map_err(|e| crate::Error::SevenzipError(e))?; + .map_err(crate::Error::SevenzipError)?; Box::new(a.into_iter()) } Gzip | Bzip | Lz4 | Lzma | Snappy | Zstd => { diff --git a/src/utils/fs.rs b/src/utils/fs.rs index 08f6d1b..dbd422e 100644 --- a/src/utils/fs.rs +++ b/src/utils/fs.rs @@ -91,6 +91,9 @@ pub fn try_infer_extension(path: &Path) -> Option { && buf.starts_with(&[0x52, 0x61, 0x72, 0x21, 0x1A, 0x07]) && (buf[6] == 0x00 || (buf.len() >= 8 && buf[6..=7] == [0x01, 0x00])) } + fn is_sevenz(buf: &[u8]) -> bool { + buf.starts_with(&[0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C]) + } let buf = { let mut buf = [0; 270]; @@ -124,6 +127,8 @@ pub fn try_infer_extension(path: &Path) -> Option { Some(Extension::new(&[Zstd], "zst")) } else if is_rar(&buf) { Some(Extension::new(&[Rar], "rar")) + } else if is_sevenz(&buf) { + Some(Extension::new(&[SevenZip], "7z")) } else { None }