aboutsummaryrefslogtreecommitdiffstats
path: root/src/archive.rs
diff options
context:
space:
mode:
authorboasting-squirrel <boasting.squirrel@gmail.com>2019-03-11 23:25:56 +0000
committerboasting-squirrel <boasting.squirrel@gmail.com>2019-03-11 23:25:56 +0000
commitaeb51dcf43665741a3438360151a4424e9b243e0 (patch)
tree8f79e2b303512468170883b1d0ada02e344a6e5b /src/archive.rs
parentChanged Info: to info: to be consistent (diff)
downloadminiserve-aeb51dcf43665741a3438360151a4424e9b243e0.tar.gz
miniserve-aeb51dcf43665741a3438360151a4424e9b243e0.zip
Started to add helpful messages for errors which could occur during archiving
Diffstat (limited to '')
-rw-r--r--src/archive.rs82
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()
+}