ouch/src/utils/mod.rs
Ryan Roden-Corrent 77c1a4e9db Support decompressing stdin.
Fixes #687.

If "-" is passed as a filename, decompress data from stdin.

Currently `--format` must be passed as well, but as a next step,
we could try to infer the format from magic numbers.

As stdin is not connected to the terminal, we cannot prompt for Y/N
when warning about decompression in memory, for e.g. zip. Just default
to No, and require passing "-y" in these cases.

For zip, we have to buffer the whole stream in memory to seek into it,
just as we do with a chained decoder like `.zip.bz`.

The rar format requires an actual file (not an `impl Read`), so
we write a temp file that it can decode.

When decoding a single-file archive (e.g. file.bz), the output filename
is just `-`, since we don't know the original filename. I had to add
a bit of a hack to the tests to work around this. Another option
would be to interpret "-d" as a destination filename in this case.

When decoding a multi-file archive, I decided to unpack directly into
the destination directory, as this seemed like a better experience than
adding a top-level "-" folder inside the destination.
2024-08-26 03:40:52 -03:00

40 lines
1.2 KiB
Rust

//! Random and miscellaneous utils used in ouch.
//!
//! In here we have the logic for custom formatting, some file and directory utils, and user
//! stdin interaction helpers.
pub mod colors;
mod file_visibility;
mod formatting;
mod fs;
pub mod io;
pub mod logger;
mod question;
pub use file_visibility::FileVisibilityPolicy;
pub use formatting::{
nice_directory_display, pretty_format_list_of_paths, strip_cur_dir, to_utf, Bytes, EscapedPathDisplay,
};
pub use fs::{
cd_into_same_dir_as, clear_path, create_dir_if_non_existent, is_path_stdin, is_symlink, remove_file_or_dir,
try_infer_extension,
};
pub use question::{
ask_to_create_file, user_wants_to_continue, user_wants_to_overwrite, QuestionAction, QuestionPolicy,
};
pub use utf8::{get_invalid_utf8_paths, is_invalid_utf8};
mod utf8 {
use std::{ffi::OsStr, path::PathBuf};
/// Check, without allocating, if os_str can be converted into &str
pub fn is_invalid_utf8(os_str: impl AsRef<OsStr>) -> bool {
os_str.as_ref().to_str().is_none()
}
/// Filter out list of paths that are not utf8 valid
pub fn get_invalid_utf8_paths(paths: &[PathBuf]) -> Vec<&PathBuf> {
paths.iter().filter(|path| is_invalid_utf8(path)).collect()
}
}