summaryrefslogtreecommitdiffstats
path: root/src/io
diff options
context:
space:
mode:
authorJeff Zhao <jeff.no.zhao@gmail.com>2022-08-01 12:34:53 -0400
committerJeff Zhao <jeff.no.zhao@gmail.com>2022-08-01 12:39:14 -0400
commit7ee7a761ec62a065fcc2bde9d98b587d069b364a (patch)
tree2ae12dd9f1e8ea089d2972f41a8f5e0393383675 /src/io
parentee0dec521b73a4328660969c3be8454dc0bf73e8 (diff)
add `symlink_files` command
Diffstat (limited to 'src/io')
-rw-r--r--src/io/file_operation.rs13
-rw-r--r--src/io/io_observer.rs1
-rw-r--r--src/io/io_worker.rs29
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>,