From d015b305f24d4acd8387dd524f750a4f64995e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mikrut?= <41945903+qarmin@users.noreply.github.com> Date: Sat, 10 Oct 2020 15:18:04 +0200 Subject: [PATCH] Add Windows support (#58) --- czkawka_core/src/big_file.rs | 8 +++++++- czkawka_core/src/common.rs | 10 ++++++++++ czkawka_core/src/common_directory.rs | 21 ++++++++++++++++++--- czkawka_core/src/duplicate.rs | 8 +++++++- czkawka_core/src/empty_files.rs | 7 ++++++- czkawka_core/src/empty_folder.rs | 8 +++++++- czkawka_core/src/temporary.rs | 12 +++++++++++- 7 files changed, 66 insertions(+), 8 deletions(-) diff --git a/czkawka_core/src/big_file.rs b/czkawka_core/src/big_file.rs index 86829c2..b3f5915 100644 --- a/czkawka_core/src/big_file.rs +++ b/czkawka_core/src/big_file.rs @@ -180,7 +180,8 @@ impl BigFile { } } // Checking files - let current_file_name = "".to_owned() + #[allow(unused_mut)] // Used is later by Windows build + let mut current_file_name = "".to_owned() + ¤t_folder + match &entry_data.file_name().into_string() { Ok(t) => t, @@ -194,6 +195,11 @@ impl BigFile { } } + #[cfg(target_family = "windows")] + { + current_file_name = Common::prettier_windows_path(¤t_file_name); + } + // Creating new file entry let fe: FileEntry = FileEntry { path: current_file_name.clone(), diff --git a/czkawka_core/src/common.rs b/czkawka_core/src/common.rs index d814db9..275ffa7 100644 --- a/czkawka_core/src/common.rs +++ b/czkawka_core/src/common.rs @@ -102,6 +102,10 @@ impl Common { } true } + #[allow(clippy::ptr_arg)] + pub fn prettier_windows_path(path_to_change: &String) -> String { + path_to_change[..1].to_uppercase() + path_to_change[1..].to_lowercase().replace("\\", "/").as_str() + } } #[cfg(test)] @@ -128,4 +132,10 @@ mod test { assert!(!Common::regex_check("*TTT", "/GGG")); assert!(!Common::regex_check("AAA", "AAA")); } + #[test] + fn test_windows_path() { + assert_eq!("C:/path.txt", Common::prettier_windows_path(&"c:/PATH.tXt".to_string())); + assert_eq!("H:/reka/weza/roman.txt", Common::prettier_windows_path(&"h:/RekA/Weza\\roMan.Txt".to_string())); + assert_eq!("T:/a", Common::prettier_windows_path(&"T:\\A".to_string())); + } } diff --git a/czkawka_core/src/common_directory.rs b/czkawka_core/src/common_directory.rs index 6d7192d..618d88e 100644 --- a/czkawka_core/src/common_directory.rs +++ b/czkawka_core/src/common_directory.rs @@ -36,10 +36,16 @@ impl Directories { text_messages.warnings.push("Included Directory Warning: Wildcards in path are not supported, ignoring ".to_string() + directory.as_str()); continue; } + #[cfg(target_family = "unix")] if !directory.starts_with('/') { text_messages.warnings.push("Included Directory Warning: Relative path are not supported, ignoring ".to_string() + directory.as_str()); continue; } + #[cfg(target_family = "windows")] + if !(directory[..directory.len()].starts_with(":/") || !directory[..directory.len()].starts_with(":\\")) { + text_messages.warnings.push("Included Directory Warning: Relative path are not supported, ignoring ".to_string() + directory.as_str()); + continue; + } if !Path::new(&directory).exists() { text_messages.warnings.push("Included Directory Warning: Provided folder path must exits, ignoring ".to_string() + directory.as_str()); continue; @@ -80,7 +86,7 @@ impl Directories { let mut checked_directories: Vec = Vec::new(); for directory in directories { - let directory: String = directory.trim().to_string(); + let directory: String = directory.trim().to_string().replace("\\", "/"); if directory == "" { continue; @@ -93,12 +99,14 @@ impl Directories { text_messages.warnings.push("Excluded Directory Warning: Wildcards in path are not supported, ignoring ".to_string() + directory.as_str()); continue; } + #[cfg(target_family = "unix")] if !directory.starts_with('/') { text_messages.warnings.push("Excluded Directory Warning: Relative path are not supported, ignoring ".to_string() + directory.as_str()); continue; } - if !Path::new(&directory).exists() { - text_messages.warnings.push("Excluded Directory Warning: Provided folder path must exits, ignoring ".to_string() + directory.as_str()); + #[cfg(target_family = "windows")] + if !(directory[..directory.len()].starts_with(":/") || !directory[..directory.len()].starts_with(":\\")) { + text_messages.warnings.push("Excluded Directory Warning: Relative path are not supported, ignoring ".to_string() + directory.as_str()); continue; } if !Path::new(&directory).is_dir() { @@ -125,6 +133,13 @@ impl Directories { let mut optimized_included: Vec = Vec::::new(); let mut optimized_excluded: Vec = Vec::::new(); + // Windows(or specific EXT4 extension) doesn't recognize size of letters so we must remove one of directory e.g. - C:/h.txt, C:/H.txt + #[cfg(target_family = "windows")] + { + self.included_directories = self.included_directories.iter().map(Common::prettier_windows_path).collect(); + self.excluded_directories = self.excluded_directories.iter().map(Common::prettier_windows_path).collect(); + } + // Remove duplicated entries like: "/", "/" self.excluded_directories.sort(); diff --git a/czkawka_core/src/duplicate.rs b/czkawka_core/src/duplicate.rs index c2d3b12..3c37943 100644 --- a/czkawka_core/src/duplicate.rs +++ b/czkawka_core/src/duplicate.rs @@ -264,7 +264,8 @@ impl DuplicateFinder { } // Checking files if metadata.len() >= self.minimal_file_size { - let current_file_name = "".to_owned() + #[allow(unused_mut)] // Used is later by Windows build + let mut current_file_name = "".to_owned() + ¤t_folder + match &entry_data.file_name().into_string() { Ok(t) => t, @@ -278,6 +279,11 @@ impl DuplicateFinder { } } + #[cfg(target_family = "windows")] + { + current_file_name = Common::prettier_windows_path(¤t_file_name); + } + // Creating new file entry let fe: FileEntry = FileEntry { path: current_file_name.clone(), diff --git a/czkawka_core/src/empty_files.rs b/czkawka_core/src/empty_files.rs index 3c982c6..fa6c678 100644 --- a/czkawka_core/src/empty_files.rs +++ b/czkawka_core/src/empty_files.rs @@ -206,7 +206,8 @@ impl EmptyFiles { } // Checking files if metadata.len() == 0 { - let current_file_name = "".to_owned() + #[allow(unused_mut)] // Used is later by Windows build + let mut current_file_name = "".to_owned() + ¤t_folder + match &entry_data.file_name().into_string() { Ok(t) => t, @@ -219,6 +220,10 @@ impl EmptyFiles { continue 'dir; } } + #[cfg(target_family = "windows")] + { + current_file_name = Common::prettier_windows_path(¤t_file_name); + } // Creating new file entry let fe: FileEntry = FileEntry { diff --git a/czkawka_core/src/empty_folder.rs b/czkawka_core/src/empty_folder.rs index e6e7a06..e303253 100644 --- a/czkawka_core/src/empty_folder.rs +++ b/czkawka_core/src/empty_folder.rs @@ -212,8 +212,14 @@ impl EmptyFolder { } // We need to set empty folder list - for (name, folder_entry) in folders_checked { + #[allow(unused_mut)] // Used is later by Windows build + for (mut name, folder_entry) in folders_checked { if folder_entry.is_empty != FolderEmptiness::No { + #[cfg(target_family = "windows")] + { + name = Common::prettier_windows_path(&name); + } + self.empty_folder_list.insert(name, folder_entry); } } diff --git a/czkawka_core/src/temporary.rs b/czkawka_core/src/temporary.rs index ef3d798..0385425 100644 --- a/czkawka_core/src/temporary.rs +++ b/czkawka_core/src/temporary.rs @@ -128,6 +128,10 @@ impl Temporary { } current_folder = folders_to_check.pop().unwrap(); + #[cfg(target_family = "windows")] + { + current_folder = Common::prettier_windows_path(¤t_folder); + } // Read current dir, if permission are denied just go to next let read_dir = match fs::read_dir(¤t_folder) { Ok(t) => t, @@ -195,7 +199,8 @@ impl Temporary { } // Checking files - let current_file_name = "".to_owned() + #[allow(unused_mut)] // Used is later by Windows build + let mut current_file_name = "".to_owned() + ¤t_folder + match &entry_data.file_name().into_string() { Ok(t) => t, @@ -209,6 +214,11 @@ impl Temporary { } } + #[cfg(target_family = "windows")] + { + current_file_name = Common::prettier_windows_path(¤t_file_name); + } + // Creating new file entry let fe: FileEntry = FileEntry { path: current_file_name.clone(),