From 5543c0c95b9f772d47adec943ecede97068a5ad5 Mon Sep 17 00:00:00 2001 From: Haruaki Tamada Date: Sat, 27 Apr 2024 23:43:39 +0900 Subject: [PATCH] implement tar+{gzip, bzip2} archiver --- Cargo.toml | 2 ++ src/archiver/rar.rs | 4 ++-- src/archiver/tar.rs | 26 ++++++++++++++++++++------ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9623370..e9ec8f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,9 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +bzip2 = "0.4.4" clap = { version = "4.5.4", features = ["derive"] } +flate2 = "1.0.29" tar = "0.4.40" time = "0.3.36" zip = "1.1.1" diff --git a/src/archiver/rar.rs b/src/archiver/rar.rs index bcfc9fd..ef57f20 100644 --- a/src/archiver/rar.rs +++ b/src/archiver/rar.rs @@ -5,8 +5,8 @@ pub struct RarArchiver { } impl Archiver for RarArchiver { - fn perform(&self, inout: InOut) -> Result<()> { - Err(ToatError::UnknownError("not implement yet".to_string())) + fn perform(&self, _: InOut) -> Result<()> { + Err(ToatError::UnsupportedFormat("only extraction support for rar".to_string())) } fn format(&self) -> Format { Format::Rar diff --git a/src/archiver/tar.rs b/src/archiver/tar.rs index 69767f6..95f11f7 100644 --- a/src/archiver/tar.rs +++ b/src/archiver/tar.rs @@ -1,5 +1,7 @@ -use std::fs::File; +use std::io::Write; use std::path::PathBuf; +use flate2::write::GzEncoder; +use bzip2::write::BzEncoder; use tar::Builder; use crate::archiver::{Archiver, InOut, Format}; @@ -27,7 +29,13 @@ impl Archiver for TarArchiver { } impl Archiver for TarGzArchiver{ fn perform(&self, inout: InOut) -> Result<()> { - Err(ToatError::UnknownError("not implement yet".to_string())) + match inout.destination() { + Err(e) => Err(e), + Ok(file) => { + let enc = GzEncoder::new(file, flate2::Compression::default()); + write_to_tar(enc, inout.targets(), inout.recursive) + } + } } fn format(&self) -> Format { Format::TarGz @@ -35,14 +43,20 @@ impl Archiver for TarGzArchiver{ } impl Archiver for TarBz2Archiver { fn perform(&self, inout: InOut) -> Result<()> { - Err(ToatError::UnknownError("not implement yet".to_string())) + match inout.destination() { + Err(e) => Err(e), + Ok(file) => { + let enc = BzEncoder::new(file, bzip2::Compression::best()); + write_to_tar(enc, inout.targets(), inout.recursive) + } + } } fn format(&self) -> Format { Format::TarBz2 } } -fn process_dir(builder: &mut Builder, target: PathBuf, recursive: bool) -> Result<()> { +fn process_dir(builder: &mut Builder, target: PathBuf, recursive: bool) -> Result<()> { if let Err(e) = builder.append_dir(&target, &target) { return Err(ToatError::ArchiverError(e.to_string())) } @@ -59,7 +73,7 @@ fn process_dir(builder: &mut Builder, target: PathBuf, recursive: bool) -> Ok(()) } -fn process_file(builder: &mut Builder, target: PathBuf) -> Result<()> { +fn process_file(builder: &mut Builder, target: PathBuf) -> Result<()> { if let Err(e) = builder.append_path(target) { Err(ToatError::ArchiverError(e.to_string())) } else { @@ -67,7 +81,7 @@ fn process_file(builder: &mut Builder, target: PathBuf) -> Result<()> { } } -fn write_to_tar(file: File, targets: Vec, recursive: bool) -> Result<()> { +fn write_to_tar(file: W, targets: Vec, recursive: bool) -> Result<()> { let mut builder = tar::Builder::new(file); for target in targets { let path = target.as_path();