compressors/zip: replace a couple of unwraps to the question mark op.
[ouch.git] / src / compressors / zip.rs
blobbcfea08f7203792ca6ddeefb4a715641c7593846
1 use std::{
2     io::{Cursor, Write},
3     path::PathBuf,
4 };
6 use walkdir::WalkDir;
8 use super::compressor::Entry;
9 use crate::{compressors::Compressor, file::File, utils};
11 pub struct ZipCompressor {}
13 impl ZipCompressor {
14     // TODO: this function does not seem to be working correctly ;/
15     fn make_archive_from_memory(input: File) -> crate::Result<Vec<u8>> {
16         let buffer = vec![];
17         let mut writer = zip::ZipWriter::new(std::io::Cursor::new(buffer));
19         let inner_file_path: Box<str> = input
20             .path
21             .file_stem()
22             .ok_or(
23                 // TODO: Is this reachable?
24                 crate::Error::InvalidInput,
25             )?
26             .to_string_lossy()
27             .into();
29         let options =
30             zip::write::FileOptions::default().compression_method(zip::CompressionMethod::Deflated);
32         writer.start_file(inner_file_path, options)?;
34         let input_bytes = match input.contents_in_memory {
35             Some(bytes) => bytes,
36             None => {
37                 // TODO: error description, although this block should not be
38                 // reachable
39                 return Err(crate::Error::InvalidInput);
40             }
41         };
43         writer.write_all(&*input_bytes)?;
45         let bytes = writer.finish().unwrap();
47         Ok(bytes.into_inner())
48     }
50     fn make_archive_from_files(input_filenames: Vec<PathBuf>) -> crate::Result<Vec<u8>> {
51         let buffer = vec![];
52         let mut writer = zip::ZipWriter::new(Cursor::new(buffer));
54         let options =
55             zip::write::FileOptions::default().compression_method(zip::CompressionMethod::Deflated);
57         for filename in input_filenames {
59             let previous_location = utils::change_dir_and_return_parent(&filename)?;
60             let filename = filename.file_name()?;
62             for entry in WalkDir::new(filename) {
63                 let entry = entry?;
64                 let entry_path = &entry.path();
65                 if entry_path.is_dir() {
66                     continue;
67                 }
68                 writer.start_file(entry_path.to_string_lossy(), options)?;
69                 let file_bytes = std::fs::read(entry.path())?;
70                 writer.write_all(&*file_bytes)?;
71             }
73             std::env::set_current_dir(previous_location)?;
74         }
76         let bytes = writer.finish()?;
78         Ok(bytes.into_inner())
79     }
82 impl Compressor for ZipCompressor {
83     fn compress(&self, from: Entry) -> crate::Result<Vec<u8>> {
84         match from {
85             Entry::Files(filenames) => Ok(Self::make_archive_from_files(filenames)?),
86             Entry::InMemory(file) => Ok(Self::make_archive_from_memory(file)?),
87         }
88     }