diff --git a/yazi-shared/src/fs/fns.rs b/yazi-shared/src/fs/fns.rs index cfd1f6d7..5dfc54d5 100644 --- a/yazi-shared/src/fs/fns.rs +++ b/yazi-shared/src/fs/fns.rs @@ -1,7 +1,14 @@ -use std::{collections::VecDeque, path::{Path, PathBuf}}; +use std::{ + collections::VecDeque, + path::{Path, PathBuf}, +}; use anyhow::Result; -use tokio::{fs, io, select, sync::{mpsc, oneshot}, time}; +use tokio::{ + fs, io, select, + sync::{mpsc, oneshot}, + time, +}; pub async fn calculate_size(path: &Path) -> u64 { let mut total = 0; @@ -38,15 +45,23 @@ pub async fn calculate_size(path: &Path) -> u64 { pub fn copy_with_progress(from: &Path, to: &Path) -> mpsc::Receiver> { let (tx, rx) = mpsc::channel(1); let (tick_tx, mut tick_rx) = oneshot::channel(); + let is_symlink = from.is_symlink(); tokio::spawn({ let (from, to) = (from.to_path_buf(), to.to_path_buf()); async move { - _ = match fs::copy(from, to).await { - Ok(len) => tick_tx.send(Ok(len)), - Err(e) => tick_tx.send(Err(e)), - }; + if is_symlink { + _ = match fs::symlink(from, to).await { + Ok(()) => tick_tx.send(Ok(1)), + Err(e) => tick_tx.send(Err(e)), + } + } else { + _ = match fs::copy(from, to).await { + Ok(len) => tick_tx.send(Ok(len)), + Err(e) => tick_tx.send(Err(e)), + }; + } } }); @@ -79,7 +94,12 @@ pub fn copy_with_progress(from: &Path, to: &Path) -> mpsc::Receiver {} } - let len = fs::symlink_metadata(&to).await.map(|m| m.len()).unwrap_or(0); + let len = if is_symlink { + 1 + } else { + fs::symlink_metadata(&to).await.map(|m| m.len()).unwrap_or(0) + }; + if len > last { tx.send(Ok(len - last)).await.ok(); last = len; @@ -95,7 +115,10 @@ pub fn copy_with_progress(from: &Path, to: &Path) -> mpsc::Receiver String { - use libc::{mode_t, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFSOCK, S_IRGRP, S_IROTH, S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR}; + use libc::{ + mode_t, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFSOCK, S_IRGRP, S_IROTH, + S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR, + }; let mut s = String::with_capacity(10); let m = mode as mode_t; @@ -115,27 +138,51 @@ pub fn permissions(mode: u32) -> String { s.push(if m & S_IRUSR != 0 { 'r' } else { '-' }); s.push(if m & S_IWUSR != 0 { 'w' } else { '-' }); s.push(if m & S_IXUSR != 0 { - if m & S_ISUID != 0 { 's' } else { 'x' } + if m & S_ISUID != 0 { + 's' + } else { + 'x' + } } else { - if m & S_ISUID != 0 { 'S' } else { '-' } + if m & S_ISUID != 0 { + 'S' + } else { + '-' + } }); // Group s.push(if m & S_IRGRP != 0 { 'r' } else { '-' }); s.push(if m & S_IWGRP != 0 { 'w' } else { '-' }); s.push(if m & S_IXGRP != 0 { - if m & S_ISGID != 0 { 's' } else { 'x' } + if m & S_ISGID != 0 { + 's' + } else { + 'x' + } } else { - if m & S_ISGID != 0 { 'S' } else { '-' } + if m & S_ISGID != 0 { + 'S' + } else { + '-' + } }); // Other s.push(if m & S_IROTH != 0 { 'r' } else { '-' }); s.push(if m & S_IWOTH != 0 { 'w' } else { '-' }); s.push(if m & S_IXOTH != 0 { - if m & S_ISVTX != 0 { 't' } else { 'x' } + if m & S_ISVTX != 0 { + 't' + } else { + 'x' + } } else { - if m & S_ISVTX != 0 { 'T' } else { '-' } + if m & S_ISVTX != 0 { + 'T' + } else { + '-' + } }); s