Refactor path equality check function to specific between unix and windows

This commit is contained in:
Shupeng Xue 2024-06-23 19:59:53 +10:00
parent 810f1d0483
commit 454530a67a
No known key found for this signature in database
GPG key ID: A6C508165D76B601
3 changed files with 21 additions and 12 deletions

View file

@ -6,7 +6,7 @@ use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}};
use yazi_config::{OPEN, PREVIEW};
use yazi_dds::Pubsub;
use yazi_proxy::{AppProxy, TasksProxy, HIDER, WATCHER};
use yazi_shared::{fs::{are_names_equal, max_common_root, maybe_exists, File, FilesOp, Url}, terminal_clear};
use yazi_shared::{fs::{are_pathss_equal, max_common_root, maybe_exists, File, FilesOp, Url}, terminal_clear};
use crate::manager::Manager;
@ -84,7 +84,7 @@ impl Manager {
for (o, n) in todo {
let (old, new) = (root.join(&o), root.join(&n));
if maybe_exists(&new).await && !are_names_equal(&old, &new) {
if maybe_exists(&new).await && !are_pathss_equal(&old, &new).await {
failed.push((o, n, anyhow!("Destination already exists")));
} else if let Err(e) = fs::rename(&old, &new).await {
failed.push((o, n, e.into()));

View file

@ -5,7 +5,7 @@ use tokio::fs;
use yazi_config::popup::InputCfg;
use yazi_dds::Pubsub;
use yazi_proxy::{InputProxy, TabProxy, WATCHER};
use yazi_shared::{event::Cmd, fs::{are_names_equal, maybe_exists, ok_or_not_found, symlink_realpath, File, FilesOp, Url}};
use yazi_shared::{event::Cmd, fs::{are_pathss_equal, maybe_exists, ok_or_not_found, symlink_realpath, File, FilesOp, Url}};
use crate::manager::Manager;
@ -62,7 +62,7 @@ impl Manager {
}
let new = hovered.parent().unwrap().join(name);
if opt.force || !maybe_exists(&new).await || are_names_equal(&hovered, &new) {
if opt.force || !maybe_exists(&new).await || are_pathss_equal(&hovered, &new).await {
Self::rename_do(tab, hovered, Url::from(new)).await.ok();
return;
}
@ -81,7 +81,7 @@ impl Manager {
let Some(p_new) = new.parent_url() else { return Ok(()) };
let _permit = WATCHER.acquire().await.unwrap();
let are_different = !are_names_equal(&old, &new);
let are_different = !are_pathss_equal(&old, &new).await;
let overwritten = symlink_realpath(&new).await;
fs::rename(&old, &new).await?;

View file

@ -24,17 +24,26 @@ pub fn ok_or_not_found(result: io::Result<()>) -> io::Result<()> {
}
#[inline]
pub fn are_names_equal(old: impl AsRef<Path>, new: impl AsRef<Path>) -> bool {
if let (Some(old), Some(new)) = (old.as_ref().file_name(), new.as_ref().file_name()) {
let (old, new) = if cfg!(target_os = "macos") || cfg!(target_os = "windows") {
(Cow::Owned(old.to_ascii_lowercase()), Cow::Owned(new.to_ascii_lowercase()))
pub async fn are_pathss_equal(old: impl AsRef<Path>, new: impl AsRef<Path>) -> bool {
#[cfg(unix)]
if let (Ok(canonical_old), Ok(canonical_new)) =
(fs::canonicalize(&old).await, fs::canonicalize(&new).await)
{
if let (Ok(old), Ok(new)) =
(fs::metadata(&canonical_old).await, fs::metadata(&canonical_new).await)
{
use std::os::unix::fs::MetadataExt;
old.ino() == new.ino() && old.dev() == new.dev()
} else {
(Cow::Borrowed(old), Cow::Borrowed(new))
};
old == new
false
}
} else {
false
}
#[cfg(windows)]
{
// TODO: use MoveFileEx without MOVEFILE_REPLACE_EXISTING
}
}
pub async fn symlink_realpath(path: &Path) -> Result<PathBuf> {