Refactor path equality check function

This commit is contained in:
Xerxes-2 2024-06-23 16:29:18 +10:00
parent 79ea19da2d
commit e86eeb5c16

View file

@ -25,27 +25,29 @@ pub fn ok_or_not_found(result: io::Result<()>) -> io::Result<()> {
#[inline] #[inline]
pub async fn are_paths_equal(old: impl AsRef<Path>, new: impl AsRef<Path>) -> bool { pub async fn are_paths_equal(old: impl AsRef<Path>, new: impl AsRef<Path>) -> bool {
#[cfg(unix)] if let (Some(old), Some(new)) = (
{ canonicalize_without_resolving_itself(old).await,
use std::os::unix::fs::MetadataExt; canonicalize_without_resolving_itself(new).await,
match (fs::symlink_metadata(old).await, fs::symlink_metadata(new).await) { ) {
(Ok(old), Ok(new)) => old.dev() == new.dev() && old.ino() == new.ino(), old == new
_ => false, } else {
} false
} }
#[cfg(windows)] }
{
use winapi_util::{file::information, Handle}; async fn canonicalize_without_resolving_itself(path: impl AsRef<Path>) -> Option<PathBuf> {
match (Handle::from_path_any(old), Handle::from_path_any(new)) { let meta = fs::symlink_metadata(&path).await.ok()?;
(Ok(old), Ok(new)) => match (information(old), information(new)) { if meta.is_symlink() {
(Ok(old), Ok(new)) => { let (parent, link) = (path.as_ref().parent()?, path.as_ref().file_name()?);
old.volume_serial_number() == new.volume_serial_number() let parent = fs::canonicalize(parent).await.ok()?;
&& old.file_index() == new.file_index() let new_link = if cfg!(target_os = "macos") || cfg!(target_os = "windows") {
} Cow::Owned(link.to_ascii_lowercase())
_ => false, } else {
}, Cow::Borrowed(link)
_ => false, };
} Some(parent.join(new_link))
} else {
fs::canonicalize(path).await.ok()
} }
} }