diff --git a/src/archive/tar.rs b/src/archive/tar.rs index d37628819..7702a48a6 100644 --- a/src/archive/tar.rs +++ b/src/archive/tar.rs @@ -15,7 +15,7 @@ use crate::{ error::FinalError, info, list::FileInArchive, - utils::{self, Bytes, EscapedPathDisplay, FileVisibilityPolicy}, + utils::{self, Bytes, FileVisibilityPolicy}, warning, }; @@ -119,7 +119,7 @@ where // spoken text for users using screen readers, braille displays // and so on if !quiet { - info!(inaccessible, "Compressing '{}'.", EscapedPathDisplay::new(path)); + info!(inaccessible, "Compressing '{}'.", path.display()); } if path.is_dir() { diff --git a/src/archive/zip.rs b/src/archive/zip.rs index 60cc440db..734c8e2dc 100644 --- a/src/archive/zip.rs +++ b/src/archive/zip.rs @@ -22,7 +22,7 @@ use crate::{ list::FileInArchive, utils::{ self, cd_into_same_dir_as, get_invalid_utf8_paths, pretty_format_list_of_paths, strip_cur_dir, Bytes, - EscapedPathDisplay, FileVisibilityPolicy, + FileVisibilityPolicy, }, warning, }; @@ -190,7 +190,7 @@ where // spoken text for users using screen readers, braille displays // and so on if !quiet { - info!(inaccessible, "Compressing '{}'.", EscapedPathDisplay::new(path)); + info!(inaccessible, "Compressing '{}'.", path.display()); } let metadata = match path.metadata() { diff --git a/src/check.rs b/src/check.rs index afb3c3b01..74ffe957c 100644 --- a/src/check.rs +++ b/src/check.rs @@ -12,7 +12,7 @@ use crate::{ error::FinalError, extension::{build_archive_file_suggestion, Extension}, info, - utils::{pretty_format_list_of_paths, try_infer_extension, user_wants_to_continue, EscapedPathDisplay}, + utils::{pretty_format_list_of_paths, try_infer_extension, user_wants_to_continue}, warning, QuestionAction, QuestionPolicy, Result, }; @@ -103,22 +103,19 @@ pub fn check_for_non_archive_formats(files: &[PathBuf], formats: &[Vec Result<()> { if let Some(format) = formats.iter().skip(1).find(|format| format.is_archive()) { - let error = FinalError::with_title(format!( - "Cannot compress to '{}'.", - EscapedPathDisplay::new(output_path) - )) - .detail(format!("Found the format '{format}' in an incorrect position.")) - .detail(format!( - "'{format}' can only be used at the start of the file extension." - )) - .hint(format!( - "If you wish to compress multiple files, start the extension with '{format}'." - )) - .hint(format!( - "Otherwise, remove the last '{}' from '{}'.", - format, - EscapedPathDisplay::new(output_path) - )); + let error = FinalError::with_title(format!("Cannot compress to '{}'.", output_path.display())) + .detail(format!("Found the format '{format}' in an incorrect position.")) + .detail(format!( + "'{format}' can only be used at the start of the file extension." + )) + .hint(format!( + "If you wish to compress multiple files, start the extension with '{format}'." + )) + .hint(format!( + "Otherwise, remove the last '{}' from '{}'.", + format, + output_path.display() + )); return Err(error.into()); } @@ -167,10 +164,7 @@ pub fn check_missing_formats_when_decompressing(files: &[PathBuf], formats: &[Ve error = error .hint("") .hint("Alternatively, you can pass an extension to the '--format' flag:") - .hint(format!( - " ouch decompress {} --format tar.gz", - EscapedPathDisplay::new(path), - )); + .hint(format!(" ouch decompress {} --format tar.gz", path.display(),)); } Err(error.into()) @@ -179,7 +173,7 @@ pub fn check_missing_formats_when_decompressing(files: &[PathBuf], formats: &[Ve /// Check if there is a first format when compressing, and returns it. pub fn check_first_format_when_compressing<'a>(formats: &'a [Extension], output_path: &Path) -> Result<&'a Extension> { formats.first().ok_or_else(|| { - let output_path = EscapedPathDisplay::new(output_path); + let output_path = output_path.display(); FinalError::with_title(format!("Cannot compress to '{output_path}'.")) .detail("You shall supply the compression format") .hint("Try adding supported extensions (see --help):") @@ -233,11 +227,11 @@ pub fn check_invalid_compression_with_non_archive_format( .expect("output path should contain a compression format"); ( - format!("From: {}", EscapedPathDisplay::new(output_path)), + format!("From: {}", output_path.display()), format!("To: {suggested_output_path}"), ) }; - let output_path = EscapedPathDisplay::new(output_path); + let output_path = output_path.display(); let error = FinalError::with_title(format!("Cannot compress to '{output_path}'.")) .detail(first_detail_message) diff --git a/src/commands/mod.rs b/src/commands/mod.rs index d8c0709ba..7a70125b2 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -17,7 +17,7 @@ use crate::{ extension::{self, parse_format_flag}, info, list::ListOptions, - utils::{self, path_to_str, EscapedPathDisplay, FileVisibilityPolicy}, + utils::{self, path_to_str, FileVisibilityPolicy}, warning, CliArgs, QuestionPolicy, }; @@ -107,10 +107,7 @@ pub fn run( // out that we left a possibly CORRUPTED file at `output_path` if utils::remove_file_or_dir(&output_path).is_err() { eprintln!("{red}FATAL ERROR:\n", red = *colors::RED); - eprintln!( - " Ouch failed to delete the file '{}'.", - EscapedPathDisplay::new(&output_path) - ); + eprintln!(" Ouch failed to delete the file '{}'.", &output_path.display()); eprintln!(" Please delete it manually."); eprintln!(" This file is corrupted if compression didn't finished."); @@ -130,7 +127,7 @@ pub fn run( let format = parse_format_flag(&format)?; for path in files.iter() { let file_name = path.file_name().ok_or_else(|| Error::NotFound { - error_title: format!("{} does not have a file name", EscapedPathDisplay::new(path)), + error_title: format!("{} does not have a file name", path.display()), })?; output_paths.push(file_name.as_ref()); formats.push(format.clone()); diff --git a/src/list.rs b/src/list.rs index 4d4a94524..026ce6efd 100644 --- a/src/list.rs +++ b/src/list.rs @@ -6,7 +6,7 @@ use std::{ }; use self::tree::Tree; -use crate::{accessible::is_running_in_accessible_mode, utils::EscapedPathDisplay}; +use crate::accessible::is_running_in_accessible_mode; /// Options controlling how archive contents should be listed #[derive(Debug, Clone, Copy)] @@ -33,7 +33,7 @@ pub fn list_files( list_options: ListOptions, ) -> crate::Result<()> { let out = &mut stdout().lock(); - let _ = writeln!(out, "Archive: {}", EscapedPathDisplay::new(archive)); + let _ = writeln!(out, "Archive: {}", archive.display()); if list_options.tree { let tree = files.into_iter().collect::>()?; @@ -41,7 +41,7 @@ pub fn list_files( } else { for file in files { let FileInArchive { path, is_dir } = file?; - print_entry(out, EscapedPathDisplay::new(&path), is_dir); + print_entry(out, &path.display(), is_dir); } } Ok(()) @@ -86,7 +86,7 @@ mod tree { use linked_hash_map::LinkedHashMap; use super::FileInArchive; - use crate::{utils::EscapedPathDisplay, warning}; + use crate::warning; /// Directory tree #[derive(Debug, Default)] @@ -122,7 +122,7 @@ mod tree { Some(file) => { warning!( "multiple files with the same name in a single directory ({})", - EscapedPathDisplay::new(&file.path), + &file.path.display(), ); } } diff --git a/src/utils/formatting.rs b/src/utils/formatting.rs index 9ebef9698..06d69c643 100644 --- a/src/utils/formatting.rs +++ b/src/utils/formatting.rs @@ -1,50 +1,11 @@ -use std::{borrow::Cow, cmp, ffi::OsStr, fmt::Display, path::Path}; +use std::{borrow::Cow, cmp, ffi::OsStr, path::Path}; use crate::CURRENT_DIRECTORY; -/// Converts invalid UTF-8 bytes to the Unicode replacement codepoint (�) in its Display implementation. -pub struct EscapedPathDisplay<'a> { - path: &'a Path, -} - -impl<'a> EscapedPathDisplay<'a> { - pub fn new(path: &'a Path) -> Self { - Self { path } - } -} - -#[cfg(unix)] -impl Display for EscapedPathDisplay<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - 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(()) - } -} - /// Converts an OsStr to utf8 with custom formatting. /// -/// This is different from [`Path::display`]. -/// -/// See for a comparison. +/// This is different from [`Path::display`], see +/// for a comparison. pub fn path_to_str(path: &Path) -> Cow { os_str_to_str(path.as_ref()) } diff --git a/src/utils/fs.rs b/src/utils/fs.rs index f6f48886d..741e59ded 100644 --- a/src/utils/fs.rs +++ b/src/utils/fs.rs @@ -9,7 +9,7 @@ use std::{ use fs_err as fs; use super::user_wants_to_overwrite; -use crate::{extension::Extension, info, utils::EscapedPathDisplay, QuestionPolicy}; +use crate::{extension::Extension, info, QuestionPolicy}; /// 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)?; // creating a directory is an important change to the file system we // should always inform the user about - info!(accessible, "directory {} created.", EscapedPathDisplay::new(path)); + info!(accessible, "directory {} created.", path.display()); } Ok(()) } diff --git a/src/utils/mod.rs b/src/utils/mod.rs index a27d6295d..398a70a02 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -13,7 +13,6 @@ pub use self::{ file_visibility::FileVisibilityPolicy, formatting::{ nice_directory_display, os_str_to_str, path_to_str, pretty_format_list_of_paths, strip_cur_dir, Bytes, - EscapedPathDisplay, }, fs::{ cd_into_same_dir_as, clear_path, create_dir_if_non_existent, is_symlink, remove_file_or_dir, diff --git a/src/utils/question.rs b/src/utils/question.rs index 92e599f65..29d0af273 100644 --- a/src/utils/question.rs +++ b/src/utils/question.rs @@ -14,7 +14,7 @@ use fs_err as fs; use crate::{ accessible::is_running_in_accessible_mode, error::{Error, FinalError, Result}, - utils::{self, colors, formatting::path_to_str, strip_cur_dir}, + utils::{self, colors, path_to_str, strip_cur_dir}, }; #[derive(Debug, PartialEq, Eq, Clone, Copy)]