diff options
author | Jeff Zhao <jeff.no.zhao@gmail.com> | 2022-08-01 12:34:53 -0400 |
---|---|---|
committer | Jeff Zhao <jeff.no.zhao@gmail.com> | 2022-08-01 12:39:14 -0400 |
commit | 7ee7a761ec62a065fcc2bde9d98b587d069b364a (patch) | |
tree | 2ae12dd9f1e8ea089d2972f41a8f5e0393383675 /src/io | |
parent | ee0dec521b73a4328660969c3be8454dc0bf73e8 (diff) |
add `symlink_files` command
Diffstat (limited to 'src/io')
-rw-r--r-- | src/io/file_operation.rs | 13 | ||||
-rw-r--r-- | src/io/io_observer.rs | 1 | ||||
-rw-r--r-- | src/io/io_worker.rs | 29 |
3 files changed, 42 insertions, 1 deletions
diff --git a/src/io/file_operation.rs b/src/io/file_operation.rs index 14693ec..9d39716 100644 --- a/src/io/file_operation.rs +++ b/src/io/file_operation.rs @@ -2,15 +2,26 @@ pub enum FileOperation { Cut, Copy, + Symlink, Delete, } +impl std::fmt::Display for FileOperation { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Self::Cut => write!(f, "Cut"), + Self::Copy => write!(f, "Copy"), + Self::Symlink => write!(f, "Symlink"), + Self::Delete => write!(f, "Delete"), + } + } +} + #[derive(Clone, Copy, Debug, Default)] pub struct FileOperationOptions { // cut, copy pub overwrite: bool, pub skip_exist: bool, - pub symlink: bool, // delete pub permanently: bool, diff --git a/src/io/io_observer.rs b/src/io/io_observer.rs index 2df4842..44d4248 100644 --- a/src/io/io_observer.rs +++ b/src/io/io_observer.rs @@ -37,6 +37,7 @@ impl IoWorkerObserver { let op_str = match progress.kind() { FileOperation::Cut => "Moving", FileOperation::Copy => "Copying", + FileOperation::Symlink => "Symlinking", FileOperation::Delete => "Deleting", }; let processed_size = format::file_size_to_string(progress.bytes_processed()); diff --git a/src/io/io_worker.rs b/src/io/io_worker.rs index 87c5bad..f9d86d9 100644 --- a/src/io/io_worker.rs +++ b/src/io/io_worker.rs @@ -4,6 +4,9 @@ use std::io; use std::path; use std::sync::mpsc; +#[cfg(unix)] +use std::os::unix; + use crate::io::{FileOperation, FileOperationOptions, FileOperationProgress}; use crate::util::name_resolution::rename_filename_conflict; @@ -41,6 +44,7 @@ impl IoWorkerThread { match self.kind() { FileOperation::Cut => self.paste_cut(tx), FileOperation::Copy => self.paste_copy(tx), + FileOperation::Symlink => self.paste_link(tx), FileOperation::Delete => self.delete(tx), } } @@ -83,6 +87,31 @@ impl IoWorkerThread { Ok(progress) } + fn paste_link( + &self, + tx: mpsc::Sender<FileOperationProgress>, + ) -> io::Result<FileOperationProgress> { + let total_files = self.paths.len(); + let total_bytes = total_files as u64; + let mut progress = FileOperationProgress::new(self.kind(), 0, total_files, 0, total_bytes); + + #[cfg(unix)] + for src in self.paths.iter() { + let _ = tx.send(progress.clone()); + let mut dest_buf = self.dest.to_path_buf(); + if let Some(s) = src.file_name() { + dest_buf.push(s); + } + if !self.options.overwrite { + rename_filename_conflict(&mut dest_buf); + } + unix::fs::symlink(src, &dest_buf)?; + progress.set_files_processed(progress.files_processed() + 1); + progress.set_bytes_processed(progress.bytes_processed() + 1); + } + Ok(progress) + } + fn delete( &self, _tx: mpsc::Sender<FileOperationProgress>, |