diff options
Diffstat (limited to '')
-rw-r--r-- | src/archive.rs | 82 |
1 files changed, 48 insertions, 34 deletions
diff --git a/src/archive.rs b/src/archive.rs index bc3a1c8..afbcc6b 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -1,5 +1,6 @@ use actix_web::http::ContentEncoding; use bytes::Bytes; +use failure::ResultExt; use libflate::gzip::Encoder; use serde::Deserialize; use std::fs::{File, OpenOptions}; @@ -7,6 +8,9 @@ use std::io::{self, Read}; use std::path::PathBuf; use tar::Builder; use tempfile::tempdir; +use yansi::Color; + +use crate::errors; /// Available compression methods #[derive(Debug, Deserialize, Clone)] @@ -45,43 +49,25 @@ impl CompressionMethod { } } -/// Possible errors -#[derive(Debug)] -pub enum CompressionError { - IOError(std::io::Error), - NoneError(std::option::NoneError), -} - -impl From<std::option::NoneError> for CompressionError { - fn from(err: std::option::NoneError) -> CompressionError { - CompressionError::NoneError(err) - } -} - -impl From<std::io::Error> for CompressionError { - fn from(err: std::io::Error) -> CompressionError { - CompressionError::IOError(err) - } -} - pub fn create_archive_file( method: &CompressionMethod, dir: &PathBuf, -) -> Result<(String, Bytes), CompressionError> { +) -> Result<(String, Bytes), errors::CompressionError> { match method { CompressionMethod::TarGz => tgz_compress(&dir), } } /// Compresses a given folder in .tar.gz format -fn tgz_compress(dir: &PathBuf) -> Result<(String, Bytes), CompressionError> { +fn tgz_compress(dir: &PathBuf) -> Result<(String, Bytes), errors::CompressionError> { let src_dir = dir.display().to_string(); let inner_folder = dir.file_name()?.to_str()?; let dst_filename = format!("{}.tar", inner_folder); let dst_tgz_filename = format!("{}.gz", dst_filename); - let tar_content = tar(src_dir, dst_filename, inner_folder.to_string())?; - let gz_data = gzip(&tar_content)?; + let tar_content = tar(src_dir, dst_filename, inner_folder.to_string()) + .context(errors::CompressionErrorKind::TarContentError)?; + let gz_data = gzip(&tar_content).context(errors::CompressionErrorKind::GZipContentError)?; let mut data = Bytes::new(); data.extend_from_slice(&gz_data); @@ -94,10 +80,13 @@ fn tar( src_dir: String, dst_filename: String, inner_folder: String, -) -> Result<Vec<u8>, CompressionError> { - let tmp_dir = tempdir()?; +) -> Result<Vec<u8>, errors::CompressionError> { + let tmp_dir = tempdir().context(errors::CompressionErrorKind::CreateTemporaryFileError)?; let dst_filepath = tmp_dir.path().join(dst_filename.clone()); - let tar_file = File::create(&dst_filepath)?; + let tar_file = + File::create(&dst_filepath).context(errors::CompressionErrorKind::CreateFileError { + path: color_path(&dst_filepath.display().to_string()), + })?; // Create a TAR file of src_dir let mut tar_builder = Builder::new(&tar_file); @@ -106,22 +95,47 @@ fn tar( // https://github.com/alexcrichton/tar-rs/issues/147 // https://github.com/alexcrichton/tar-rs/issues/174 tar_builder.follow_symlinks(false); - tar_builder.append_dir_all(inner_folder, src_dir)?; - tar_builder.into_inner()?; + tar_builder.append_dir_all(inner_folder, &src_dir).context( + errors::CompressionErrorKind::TarBuildingError { + message: format!( + "failed to append the content of {} in the TAR archive", + color_path(&src_dir) + ), + }, + )?; + tar_builder + .into_inner() + .context(errors::CompressionErrorKind::TarBuildingError { + message: "failed to finish writing the TAR archive".to_string(), + })?; // Read the content of the TAR file and store it as bytes - let mut tar_file = OpenOptions::new().read(true).open(&dst_filepath)?; + let mut tar_file = OpenOptions::new().read(true).open(&dst_filepath).context( + errors::CompressionErrorKind::OpenFileError { + path: color_path(&dst_filepath.display().to_string()), + }, + )?; let mut tar_content = Vec::new(); - tar_file.read_to_end(&mut tar_content)?; + tar_file + .read_to_end(&mut tar_content) + .context(errors::CompressionErrorKind::TarContentError)?; Ok(tar_content) } /// Compresses a stream of bytes using the GZIP algorithm -fn gzip(mut data: &[u8]) -> Result<Vec<u8>, CompressionError> { - let mut encoder = Encoder::new(Vec::new())?; - io::copy(&mut data, &mut encoder)?; - let data = encoder.finish().into_result()?; +fn gzip(mut data: &[u8]) -> Result<Vec<u8>, errors::CompressionError> { + let mut encoder = + Encoder::new(Vec::new()).context(errors::CompressionErrorKind::GZipBuildingError)?; + io::copy(&mut data, &mut encoder).context(errors::CompressionErrorKind::GZipBuildingError)?; + let data = encoder + .finish() + .into_result() + .context(errors::CompressionErrorKind::GZipBuildingError)?; Ok(data) } + +fn color_path(path: &str) -> String { + Color::White.paint(path).bold().to_string() +} |