diff --git a/src/commands/compress.rs b/src/commands/compress.rs index 30a6460..2ee20c5 100644 --- a/src/commands/compress.rs +++ b/src/commands/compress.rs @@ -13,6 +13,8 @@ use crate::{ QuestionAction, QuestionPolicy, BUFFER_CAPACITY, }; +use super::copy_recursively; + /// Compress files into `output_file`. /// /// # Arguments: @@ -127,10 +129,18 @@ pub fn compress_files( return Ok(false); }, SevenZip => { - for file in files.iter() { - sevenz_rust::compress_to_path(file.as_path(), output_path).unwrap(); - // todo error return + let tmpdir = tempfile::tempdir()?; + + for filep in files.iter() { + if filep.is_dir() { + copy_recursively(filep, tmpdir.path() + .join(filep.strip_prefix(std::env::current_dir()?).expect("copy folder error")))?; + } else { + fs::copy(filep, tmpdir.path().join(filep.file_name().expect("no filename in file")))?; + } } + + sevenz_rust::compress_to_path(tmpdir.path(), output_path).expect("can't compress 7zip archive"); } } diff --git a/src/commands/decompress.rs b/src/commands/decompress.rs index e9539f5..d7243cc 100644 --- a/src/commands/decompress.rs +++ b/src/commands/decompress.rs @@ -165,7 +165,7 @@ pub fn decompress_file( } }, SevenZip => { - sevenz_rust::decompress_file(input_file_path, output_dir).unwrap(); // todo error return + sevenz_rust::decompress_file(input_file_path, output_dir).expect("can't decompress"); 1 } }; diff --git a/src/commands/list.rs b/src/commands/list.rs index 270da8a..5ddbd71 100644 --- a/src/commands/list.rs +++ b/src/commands/list.rs @@ -1,6 +1,7 @@ use std::{ io::{self, BufReader, Read}, path::Path, + cell::RefCell }; use fs_err as fs; @@ -88,13 +89,13 @@ pub fn list_archive_contents( } }, SevenZip => { - let mut a = Vec::new(); + let a = RefCell::new(Vec::new()); sevenz_rust::decompress_file_with_extract_fn(archive_path, ".", |entry, _, _| { - a.push(Ok(FileInArchive{path: entry.name().into(), is_dir: entry.is_directory()})); + a.borrow_mut().push(Ok(FileInArchive{path: entry.name().into(), is_dir: entry.is_directory()})); Ok(true) - }); - Box::new(a.into_iter()) + }).expect("failed to get 7z file list"); + Box::new(a.into_inner().into_iter()) } Gzip | Bzip | Lz4 | Lzma | Snappy | Zstd => { panic!("Not an archive! This should never happen, if it does, something is wrong with `CompressionFormat::is_archive()`. Please report this error!"); diff --git a/src/commands/mod.rs b/src/commands/mod.rs index e5be233..d4d3e86 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -4,7 +4,7 @@ mod compress; mod decompress; mod list; -use std::{ops::ControlFlow, path::PathBuf}; +use std::{ops::ControlFlow, path::{PathBuf, Path}, fs}; use rayon::prelude::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use utils::colors; @@ -21,6 +21,21 @@ use crate::{ warning, CliArgs, QuestionPolicy, }; +/// Copy files from source to destination recursively. +fn copy_recursively(source: impl AsRef, destination: impl AsRef) -> std::io::Result<()> { + fs::create_dir_all(&destination)?; + for entry in fs::read_dir(source)? { + let entry = entry?; + let filetype = entry.file_type()?; + if filetype.is_dir() { + copy_recursively(entry.path(), destination.as_ref().join(entry.file_name()))?; + } else { + fs::copy(entry.path(), destination.as_ref().join(entry.file_name()))?; + } + } + Ok(()) +} + /// Warn the user that (de)compressing this .zip archive might freeze their system. fn warn_user_about_loading_zip_in_memory() { const ZIP_IN_MEMORY_LIMITATION_WARNING: &str = "\n\