1 //! Contains Tar-specific building and unpacking functions
20 /// Unpacks the archive given by `archive` into the folder given by `into`.
21 /// Assumes that output_folder is empty
22 pub fn unpack_archive(
23 reader: Box<dyn Read>,
25 mut display_handle: impl Write,
26 ) -> crate::Result<Vec<PathBuf>> {
27 assert!(output_folder.read_dir().expect("dir exists").count() == 0);
28 let mut archive = tar::Archive::new(reader);
30 let mut files_unpacked = vec![];
31 for file in archive.entries()? {
34 let file_path = output_folder.join(file.path()?);
35 file.unpack_in(output_folder)?;
37 // This is printed for every file in the archive and has little
38 // importance for most users, but would generate lots of
39 // spoken text for users using screen readers, braille displays
41 info!(@display_handle, inaccessible, "{:?} extracted. ({})", output_folder.join(file.path()?), Bytes::new(file.size()));
43 files_unpacked.push(file_path);
49 /// List contents of `archive`, returning a vector of archive entries
50 pub fn list_archive(reader: Box<dyn Read>) -> crate::Result<Vec<FileInArchive>> {
51 let mut archive = tar::Archive::new(reader);
53 let mut files = vec![];
54 for file in archive.entries()? {
57 let path = file.path()?.into_owned();
58 let is_dir = file.header().entry_type().is_dir();
60 files.push(FileInArchive { path, is_dir });
66 /// Compresses the archives given by `input_filenames` into the file given previously to `writer`.
67 pub fn build_archive_from_paths<W, D>(input_filenames: &[PathBuf], writer: W, mut display_handle: D) -> crate::Result<W>
72 let mut builder = tar::Builder::new(writer);
74 for filename in input_filenames {
75 let previous_location = utils::cd_into_same_dir_as(filename)?;
77 // Safe unwrap, input shall be treated before
78 let filename = filename.file_name().unwrap();
80 for entry in WalkDir::new(&filename) {
82 let path = entry.path();
84 // This is printed for every file in `input_filenames` and has
85 // little importance for most users, but would generate lots of
86 // spoken text for users using screen readers, braille displays
88 info!(@display_handle, inaccessible, "Compressing '{}'.", utils::to_utf(path));
91 builder.append_dir(path, path)?;
93 let mut file = fs::File::open(path)?;
94 builder.append_file(path, file.file_mut()).map_err(|err| {
95 FinalError::with_title("Could not create archive")
96 .detail("Unexpected error while trying to read file")
97 .detail(format!("Error: {}.", err))
101 env::set_current_dir(previous_location)?;
104 Ok(builder.into_inner()?)