mirror of
https://github.com/ouch-org/ouch.git
synced 2025-06-07 12:05:46 +00:00
refac: add support for Windows in EscapedPathDisplay
This commit is contained in:
parent
0deb18289a
commit
2caeb1004c
@ -16,7 +16,7 @@ use crate::{
|
|||||||
error::FinalError,
|
error::FinalError,
|
||||||
info,
|
info,
|
||||||
list::FileInArchive,
|
list::FileInArchive,
|
||||||
utils::{self, EscapedUtf8Display, FileVisibilityPolicy},
|
utils::{self, EscapedPathDisplay, FileVisibilityPolicy},
|
||||||
warning,
|
warning,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ where
|
|||||||
// spoken text for users using screen readers, braille displays
|
// spoken text for users using screen readers, braille displays
|
||||||
// and so on
|
// and so on
|
||||||
if !quiet {
|
if !quiet {
|
||||||
info!(inaccessible, "Compressing '{}'.", EscapedUtf8Display::new(path));
|
info!(inaccessible, "Compressing '{}'.", EscapedPathDisplay::new(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
if path.is_dir() {
|
if path.is_dir() {
|
||||||
|
@ -22,7 +22,7 @@ use crate::{
|
|||||||
list::FileInArchive,
|
list::FileInArchive,
|
||||||
utils::{
|
utils::{
|
||||||
self, cd_into_same_dir_as, get_invalid_utf8_paths, pretty_format_list_of_paths, strip_cur_dir,
|
self, cd_into_same_dir_as, get_invalid_utf8_paths, pretty_format_list_of_paths, strip_cur_dir,
|
||||||
EscapedUtf8Display, FileVisibilityPolicy,
|
EscapedPathDisplay, FileVisibilityPolicy,
|
||||||
},
|
},
|
||||||
warning,
|
warning,
|
||||||
};
|
};
|
||||||
@ -191,7 +191,7 @@ where
|
|||||||
// spoken text for users using screen readers, braille displays
|
// spoken text for users using screen readers, braille displays
|
||||||
// and so on
|
// and so on
|
||||||
if !quiet {
|
if !quiet {
|
||||||
info!(inaccessible, "Compressing '{}'.", EscapedUtf8Display::new(path));
|
info!(inaccessible, "Compressing '{}'.", EscapedPathDisplay::new(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
let metadata = match path.metadata() {
|
let metadata = match path.metadata() {
|
||||||
|
@ -18,7 +18,7 @@ use crate::{
|
|||||||
info,
|
info,
|
||||||
list::ListOptions,
|
list::ListOptions,
|
||||||
utils::{
|
utils::{
|
||||||
self, pretty_format_list_of_paths, to_utf, try_infer_extension, user_wants_to_continue, EscapedUtf8Display,
|
self, pretty_format_list_of_paths, to_utf, try_infer_extension, user_wants_to_continue, EscapedPathDisplay,
|
||||||
FileVisibilityPolicy,
|
FileVisibilityPolicy,
|
||||||
},
|
},
|
||||||
warning, Opts, QuestionAction, QuestionPolicy, Subcommand,
|
warning, Opts, QuestionAction, QuestionPolicy, Subcommand,
|
||||||
@ -116,7 +116,7 @@ pub fn run(
|
|||||||
let formats = extension::extensions_from_path(&output_path);
|
let formats = extension::extensions_from_path(&output_path);
|
||||||
|
|
||||||
let first_format = formats.first().ok_or_else(|| {
|
let first_format = formats.first().ok_or_else(|| {
|
||||||
let output_path = EscapedUtf8Display::new(&output_path);
|
let output_path = EscapedPathDisplay::new(&output_path);
|
||||||
FinalError::with_title(format!("Cannot compress to '{output_path}'."))
|
FinalError::with_title(format!("Cannot compress to '{output_path}'."))
|
||||||
.detail("You shall supply the compression format")
|
.detail("You shall supply the compression format")
|
||||||
.hint("Try adding supported extensions (see --help):")
|
.hint("Try adding supported extensions (see --help):")
|
||||||
@ -139,7 +139,7 @@ pub fn run(
|
|||||||
// To file.tar.bz.xz
|
// To file.tar.bz.xz
|
||||||
let suggested_output_path = build_archive_file_suggestion(&output_path, ".tar")
|
let suggested_output_path = build_archive_file_suggestion(&output_path, ".tar")
|
||||||
.expect("output path should contain a compression format");
|
.expect("output path should contain a compression format");
|
||||||
let output_path = EscapedUtf8Display::new(&output_path);
|
let output_path = EscapedPathDisplay::new(&output_path);
|
||||||
let first_detail_message = if is_multiple_inputs {
|
let first_detail_message = if is_multiple_inputs {
|
||||||
"You are trying to compress multiple files."
|
"You are trying to compress multiple files."
|
||||||
} else {
|
} else {
|
||||||
@ -163,7 +163,7 @@ pub fn run(
|
|||||||
if let Some(format) = formats.iter().skip(1).find(|format| format.is_archive()) {
|
if let Some(format) = formats.iter().skip(1).find(|format| format.is_archive()) {
|
||||||
let error = FinalError::with_title(format!(
|
let error = FinalError::with_title(format!(
|
||||||
"Cannot compress to '{}'.",
|
"Cannot compress to '{}'.",
|
||||||
EscapedUtf8Display::new(&output_path)
|
EscapedPathDisplay::new(&output_path)
|
||||||
))
|
))
|
||||||
.detail(format!("Found the format '{}' in an incorrect position.", format))
|
.detail(format!("Found the format '{}' in an incorrect position.", format))
|
||||||
.detail(format!(
|
.detail(format!(
|
||||||
@ -177,7 +177,7 @@ pub fn run(
|
|||||||
.hint(format!(
|
.hint(format!(
|
||||||
"Otherwise, remove the last '{}' from '{}'.",
|
"Otherwise, remove the last '{}' from '{}'.",
|
||||||
format,
|
format,
|
||||||
EscapedUtf8Display::new(&output_path)
|
EscapedPathDisplay::new(&output_path)
|
||||||
));
|
));
|
||||||
|
|
||||||
return Err(error.into());
|
return Err(error.into());
|
||||||
@ -213,7 +213,7 @@ pub fn run(
|
|||||||
eprintln!("{red}FATAL ERROR:\n", red = *colors::RED);
|
eprintln!("{red}FATAL ERROR:\n", red = *colors::RED);
|
||||||
eprintln!(
|
eprintln!(
|
||||||
" Ouch failed to delete the file '{}'.",
|
" Ouch failed to delete the file '{}'.",
|
||||||
EscapedUtf8Display::new(&output_path)
|
EscapedPathDisplay::new(&output_path)
|
||||||
);
|
);
|
||||||
eprintln!(" Please delete it manually.");
|
eprintln!(" Please delete it manually.");
|
||||||
eprintln!(" This file is corrupted if compression didn't finished.");
|
eprintln!(" This file is corrupted if compression didn't finished.");
|
||||||
|
@ -1,27 +1,42 @@
|
|||||||
use std::{borrow::Cow, fmt::Display, path::Path};
|
use std::{borrow::Cow, fmt::Display, path::Path};
|
||||||
|
|
||||||
use bstr::BStr;
|
|
||||||
|
|
||||||
use crate::CURRENT_DIRECTORY;
|
use crate::CURRENT_DIRECTORY;
|
||||||
|
|
||||||
/// Converts invalid UTF-8 bytes to the Unicode replacement codepoint (<28>) in its Display implementation.
|
/// Converts invalid UTF-8 bytes to the Unicode replacement codepoint (<28>) in its Display implementation.
|
||||||
pub struct EscapedUtf8Display<'a> {
|
pub struct EscapedPathDisplay<'a> {
|
||||||
bstr: &'a BStr,
|
path: &'a Path,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EscapedUtf8Display<'a> {
|
impl<'a> EscapedPathDisplay<'a> {
|
||||||
pub fn new(path: &'a Path) -> Self {
|
pub fn new(path: &'a Path) -> Self {
|
||||||
use std::os::unix::prelude::OsStrExt;
|
Self { path }
|
||||||
|
|
||||||
let bytes = path.as_os_str().as_bytes();
|
|
||||||
|
|
||||||
Self { bstr: BStr::new(bytes) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for EscapedUtf8Display<'_> {
|
#[cfg(unix)]
|
||||||
|
impl Display for EscapedPathDisplay<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "{}", self.bstr)
|
use std::os::unix::prelude::OsStrExt;
|
||||||
|
|
||||||
|
let bstr = bstr::BStr::new(self.path.as_os_str().as_bytes());
|
||||||
|
|
||||||
|
write!(f, "{}", bstr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
impl Display for EscapedPathDisplay<'_> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
use std::{char, fmt::Write, os::windows::prelude::OsStrExt};
|
||||||
|
|
||||||
|
let utf16 = self.path.as_os_str().encode_wide();
|
||||||
|
let chars = char::decode_utf16(utf16).map(|decoded| decoded.unwrap_or(char::REPLACEMENT_CHARACTER));
|
||||||
|
|
||||||
|
for char in chars {
|
||||||
|
f.write_char(char)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use std::{
|
|||||||
use fs_err as fs;
|
use fs_err as fs;
|
||||||
|
|
||||||
use super::user_wants_to_overwrite;
|
use super::user_wants_to_overwrite;
|
||||||
use crate::{extension::Extension, info, utils::EscapedUtf8Display, QuestionPolicy};
|
use crate::{extension::Extension, info, utils::EscapedPathDisplay, QuestionPolicy};
|
||||||
|
|
||||||
/// Remove `path` asking the user to overwrite if necessary.
|
/// Remove `path` asking the user to overwrite if necessary.
|
||||||
///
|
///
|
||||||
@ -41,7 +41,7 @@ pub fn create_dir_if_non_existent(path: &Path) -> crate::Result<()> {
|
|||||||
fs::create_dir_all(path)?;
|
fs::create_dir_all(path)?;
|
||||||
// creating a directory is an important change to the file system we
|
// creating a directory is an important change to the file system we
|
||||||
// should always inform the user about
|
// should always inform the user about
|
||||||
info!(accessible, "directory {} created.", EscapedUtf8Display::new(path));
|
info!(accessible, "directory {} created.", EscapedPathDisplay::new(path));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ mod fs;
|
|||||||
mod question;
|
mod question;
|
||||||
|
|
||||||
pub use file_visibility::FileVisibilityPolicy;
|
pub use file_visibility::FileVisibilityPolicy;
|
||||||
pub use formatting::{nice_directory_display, pretty_format_list_of_paths, strip_cur_dir, to_utf, EscapedUtf8Display};
|
pub use formatting::{nice_directory_display, pretty_format_list_of_paths, strip_cur_dir, to_utf, EscapedPathDisplay};
|
||||||
pub use fs::{
|
pub use fs::{
|
||||||
cd_into_same_dir_as, clear_path, create_dir_if_non_existent, is_symlink, remove_file_or_dir, try_infer_extension,
|
cd_into_same_dir_as, clear_path, create_dir_if_non_existent, is_symlink, remove_file_or_dir, try_infer_extension,
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user