From bb5be0bfdbba9aa16e37e4038daaa7008e7b22de Mon Sep 17 00:00:00 2001 From: urin Date: Sun, 19 Feb 2023 21:13:34 +0900 Subject: [PATCH] feat: ignore case in case of Windows --- README.md | 2 -- src/lib.rs | 21 +++++++++++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3ee07cb..d6030eb 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,6 @@ - Given paths have to be convertible to UTF-8. - Collisions are detected *as much as possible*, but *not perfectly*. Does not verify all paths such as hard links and symbolic links. -- Operations are validated case-sensitively even if the platform is Windows. ## Usage 🚀 @@ -118,7 +117,6 @@ cargo make setup ## TODOs ✅ -- Ignore case in case of Windows - Add demos to README - Package for various platforms - Overwrite option diff --git a/src/lib.rs b/src/lib.rs index 3ea1034..d4d3f48 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -81,9 +81,19 @@ trait PathUtilExt { /// NOTE Can be replaced with `std::path::absolute` in the future. fn absolute(&self) -> Result; fn is_hidden(&self) -> Result; + fn is_identical(&self, other: &Path) -> bool; } impl PathUtilExt for Path { + fn is_identical(&self, other: &Path) -> bool { + if cfg!(target_family = "windows") { + self == other + || self.as_os_str().to_ascii_lowercase() == other.as_os_str().to_ascii_lowercase() + } else { + self == other + } + } + #[cfg(target_family = "windows")] fn absolute(&self) -> Result { self.normalize_virtually().with_context(|| { @@ -258,7 +268,7 @@ pub fn put_source(sources: &mut Vec, path: &Path, args: &CommandLine) -> })?, }; for src in sources.iter() { - if src.abs == new_src.abs { + if src.abs.is_identical(&new_src.abs) { anyhow::bail!( "Duplicated source. {}", new_src.abs.to_string_lossy().yellow().underline() @@ -392,12 +402,15 @@ pub fn is_operational(operations: &[Operation], new_operation: &Operation) -> Re src.text.underline() ) } - if operations.iter().any(|o| o.dst.path == dst.path) { + if operations + .iter() + .any(|o| o.dst.path.is_identical(&dst.path)) + { anyhow::bail!("Duplicated destination. {}", dst.text.yellow().underline()); } if operations .iter() - .any(|o| o.dst.path.ancestors().any(|a| a == dst.path)) + .any(|o| o.dst.path.ancestors().any(|a| a.is_identical(&dst.path))) { anyhow::bail!( "Destination should not be included in other destination. {}", @@ -407,7 +420,7 @@ pub fn is_operational(operations: &[Operation], new_operation: &Operation) -> Re if dst.path.exists() { anyhow::bail!("Destination exists. {}", dst.text.yellow().underline()) } - if dst.path.ancestors().any(|d| d == src.path) { + if dst.path.ancestors().any(|d| d.is_identical(&src.path)) { anyhow::bail!( "Destination should not be included in source.\n\ Source: {}\n\