this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at bdd902269b57947f3d8bebccb528b8a9482993fe 105 lines 3.5 kB view raw
1use crate::utils::*; 2use bzip2::write::{BzDecoder, BzEncoder}; 3use bzip2::Compression; 4use std::{ 5 fs::File, 6 io::{self, Read, Write}, 7}; 8 9pub struct Bzip2 { 10 pub level: u32, // 0-9 11} 12 13impl Default for Bzip2 { 14 fn default() -> Self { 15 Bzip2 { level: 6 } 16 } 17} 18 19impl Compressor for Bzip2 { 20 /// The standard extension for the bz2 format. 21 fn extension(&self) -> &str { 22 "bz2" 23 } 24 25 /// Full name for bz2. 26 fn name(&self) -> &str { 27 "bzip2" 28 } 29 30 /// Compress an input file or pipe to a bz2 archive 31 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result<(), io::Error> { 32 let mut input_stream = match input { 33 CmprssInput::Path(paths) => { 34 if paths.len() > 1 { 35 return cmprss_error("only 1 file can be compressed at a time"); 36 } 37 Box::new(File::open(paths[0].as_path())?) 38 } 39 CmprssInput::Pipe(pipe) => Box::new(pipe) as Box<dyn Read + Send>, 40 }; 41 let output_stream: Box<dyn Write + Send> = match output { 42 CmprssOutput::Path(path) => Box::new(File::create(path)?), 43 CmprssOutput::Pipe(pipe) => Box::new(pipe) as Box<dyn Write + Send>, 44 }; 45 let mut encoder = BzEncoder::new(output_stream, Compression::new(self.level)); 46 io::copy(&mut input_stream, &mut encoder)?; 47 Ok(()) 48 } 49 50 /// Extract a bz2 archive to a file or pipe 51 fn extract(&self, input: CmprssInput, output: CmprssOutput) -> Result<(), io::Error> { 52 let mut input_stream = match input { 53 CmprssInput::Path(paths) => { 54 if paths.len() > 1 { 55 return cmprss_error("only 1 file can be extracted at a time"); 56 } 57 Box::new(File::open(paths[0].as_path())?) 58 } 59 CmprssInput::Pipe(pipe) => Box::new(pipe) as Box<dyn Read + Send>, 60 }; 61 let output_stream: Box<dyn Write + Send> = match output { 62 CmprssOutput::Path(path) => Box::new(File::create(path)?), 63 CmprssOutput::Pipe(pipe) => Box::new(pipe) as Box<dyn Write + Send>, 64 }; 65 let mut decoder = BzDecoder::new(output_stream); 66 io::copy(&mut input_stream, &mut decoder)?; 67 Ok(()) 68 } 69} 70 71#[cfg(test)] 72mod tests { 73 use super::*; 74 use assert_fs::prelude::*; 75 use predicates::prelude::*; 76 77 #[test] 78 fn roundtrip() -> Result<(), Box<dyn std::error::Error>> { 79 let compressor = Bzip2::default(); 80 81 let file = assert_fs::NamedTempFile::new("test.txt")?; 82 file.write_str("garbage data for testing")?; 83 let working_dir = assert_fs::TempDir::new()?; 84 let archive = working_dir.child("archive.".to_owned() + compressor.extension()); 85 archive.assert(predicate::path::missing()); 86 87 // Roundtrip compress/extract 88 compressor.compress( 89 CmprssInput::Path(vec![file.path().to_path_buf()]), 90 CmprssOutput::Path(archive.path().to_path_buf()), 91 )?; 92 archive.assert(predicate::path::is_file()); 93 compressor.extract( 94 CmprssInput::Path(vec![archive.path().to_path_buf()]), 95 CmprssOutput::Path(working_dir.child("test.txt").path().to_path_buf()), 96 )?; 97 98 // Assert the files are identical 99 working_dir 100 .child("test.txt") 101 .assert(predicate::path::eq_file(file.path())); 102 103 Ok(()) 104 } 105}