From becbb90b2f22d58c98693d653f55ba604bb03f75 Mon Sep 17 00:00:00 2001 From: Jiayi Zhao Date: Sun, 9 Feb 2020 12:39:31 -0500 Subject: rework input thread and file operations - no longer depend on fs_extra for copy/paste files - in house solution preserves permissions - ioworkers are now queued, no more parallel io tasks - input thread now listens for ioworker threads as well - cargo fmt --- src/fs/fs_extra_extra.rs | 323 ----------------------------------------------- src/fs/mod.rs | 1 - 2 files changed, 324 deletions(-) delete mode 100644 src/fs/fs_extra_extra.rs (limited to 'src/fs') diff --git a/src/fs/fs_extra_extra.rs b/src/fs/fs_extra_extra.rs deleted file mode 100644 index 9bc3458..0000000 --- a/src/fs/fs_extra_extra.rs +++ /dev/null @@ -1,323 +0,0 @@ -use std::path; - -fn rename_filename_conflict(mut path: path::PathBuf) -> path::PathBuf { - let file_name = path.file_name().unwrap().to_os_string(); - for i in 0.. { - if !path.exists() { - break; - } - path.pop(); - - let mut file_name = file_name.clone(); - file_name.push(&format!("_{}", i)); - path.push(file_name); - } - path -} - -pub fn fs_copy_with_progress( - paths: &[P], - to: Q, - mut options: fs_extra::dir::CopyOptions, - mut progress_handler: F, -) -> std::io::Result -where - P: AsRef, - Q: AsRef, - F: FnMut(fs_extra::TransitProcess) -> fs_extra::dir::TransitProcessResult, -{ - let total_size = { - let mut sum = 0; - for item in paths { - sum += match fs_extra::dir::get_size(item) { - Ok(s) => s, - Err(e) => { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - format!("{}", e), - )); - } - } - } - sum - }; - - let mut info_process = fs_extra::TransitProcess { - copied_bytes: 0, - total_bytes: total_size, - file_bytes_copied: 0, - file_total_bytes: 0, - file_name: String::new(), - dir_name: String::new(), - state: fs_extra::dir::TransitState::Normal, - }; - - let mut result: u64 = 0; - - let mut file_options = fs_extra::file::CopyOptions::new(); - file_options.overwrite = options.overwrite; - file_options.skip_exist = options.skip_exist; - file_options.buffer_size = options.buffer_size; - - let dir_options = options.clone(); - - let mut destination = to.as_ref().clone().to_path_buf(); - for path in paths { - let file_name = path.as_ref().file_name().unwrap().to_os_string(); - destination.push(file_name.clone()); - if !options.skip_exist { - destination = rename_filename_conflict(destination); - } - - if path.as_ref().is_dir() { - /* create the destination dir */ - std::fs::create_dir(&destination)?; - - for entry in std::fs::read_dir(path)? { - let entry = entry?; - let entry_path = entry.path(); - if entry_path.is_dir() { - let dir_handler = |info: fs_extra::dir::TransitProcess| { - info_process.copied_bytes = result + info.copied_bytes; - info_process.state = info.state; - info_process.file_name = info.file_name; - let result = progress_handler(info_process.clone()); - match result { - fs_extra::dir::TransitProcessResult::OverwriteAll => { - options.overwrite = true - } - fs_extra::dir::TransitProcessResult::SkipAll => { - options.skip_exist = true - } - _ => {} - } - result - }; - match fs_extra::dir::copy_with_progress( - &entry_path, - &destination, - &dir_options, - dir_handler, - ) { - Ok(s) => result += s, - Err(e) => { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - format!("{}", e), - )); - } - } - } else { - let file_name = entry.file_name(); - destination.push(file_name.clone()); - let file_handler = |info: fs_extra::file::TransitProcess| { - info_process.copied_bytes = result + info.copied_bytes; - info_process.file_bytes_copied = info.copied_bytes; - progress_handler(info_process.clone()); - }; - match fs_extra::file::copy_with_progress( - &entry_path, - &destination, - &file_options, - file_handler, - ) { - Ok(s) => result += s, - Err(e) => { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - format!("{}", e), - )); - } - } - destination.pop(); - } - } - } else { - let file_handler = |info: fs_extra::file::TransitProcess| { - info_process.copied_bytes = result + info.copied_bytes; - info_process.file_bytes_copied = info.copied_bytes; - progress_handler(info_process.clone()); - }; - - match fs_extra::file::copy_with_progress( - path, - &destination, - &file_options, - file_handler, - ) { - Ok(s) => result += s, - Err(e) => { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - format!("{}", e), - )); - } - } - } - destination.pop(); - } - Ok(result) -} - -pub fn fs_cut_with_progress( - paths: &[P], - to: Q, - mut options: fs_extra::dir::CopyOptions, - mut progress_handler: F, -) -> std::io::Result -where - P: AsRef, - Q: AsRef, - F: FnMut(fs_extra::TransitProcess) -> fs_extra::dir::TransitProcessResult, -{ - let total_size = { - let mut sum = 0; - for item in paths { - sum += match fs_extra::dir::get_size(item) { - Ok(s) => s, - Err(e) => { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - format!("{}", e), - )); - } - } - } - sum - }; - - let mut info_process = fs_extra::TransitProcess { - copied_bytes: 0, - total_bytes: total_size, - file_bytes_copied: 0, - file_total_bytes: 0, - file_name: String::new(), - dir_name: String::new(), - state: fs_extra::dir::TransitState::Normal, - }; - - let mut result: u64 = 0; - #[cfg(target_os = "linux")] - use std::os::linux::fs::MetadataExt; - let to_ino = to.as_ref().metadata()?.st_dev(); - - let mut destination = to.as_ref().clone().to_path_buf(); - - let mut file_options = fs_extra::file::CopyOptions::new(); - file_options.overwrite = options.overwrite; - file_options.skip_exist = options.skip_exist; - file_options.buffer_size = options.buffer_size; - - let dir_options = options.clone(); - - for path in paths { - let file_name = path.as_ref().file_name().unwrap().to_os_string(); - destination.push(file_name.clone()); - if !options.skip_exist { - destination = rename_filename_conflict(destination); - } - #[cfg(target_os = "linux")] - { - let path_ino = path.as_ref().metadata()?.st_dev(); - /* on the same fs, can do a rename */ - if path_ino == to_ino { - std::fs::rename(&path, &destination)?; - result += fs_extra::dir::get_size(&destination).unwrap(); - info_process.copied_bytes = result; - - destination.pop(); - continue; - } - } - - if path.as_ref().is_dir() { - /* create the destination dir */ - std::fs::create_dir(&destination)?; - - for entry in std::fs::read_dir(path)? { - let entry = entry?; - let entry_path = entry.path(); - if entry_path.is_dir() { - let dir_handler = |info: fs_extra::dir::TransitProcess| { - info_process.copied_bytes = result + info.copied_bytes; - info_process.state = info.state; - let result = progress_handler(info_process.clone()); - match result { - fs_extra::dir::TransitProcessResult::OverwriteAll => { - options.overwrite = true - } - fs_extra::dir::TransitProcessResult::SkipAll => { - options.skip_exist = true - } - _ => {} - } - result - }; - match fs_extra::dir::move_dir_with_progress( - &entry_path, - &destination, - &dir_options, - dir_handler, - ) { - Ok(s) => result += s, - Err(e) => { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - format!("{}", e), - )); - } - } - } else { - let file_name = entry.file_name(); - destination.push(file_name.clone()); - let file_handler = |info: fs_extra::file::TransitProcess| { - info_process.copied_bytes = result + info.copied_bytes; - info_process.file_bytes_copied = info.copied_bytes; - progress_handler(info_process.clone()); - }; - match fs_extra::file::move_file_with_progress( - &entry_path, - &destination, - &file_options, - file_handler, - ) { - Ok(s) => result += s, - Err(e) => { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - format!("{}", e), - )); - } - } - destination.pop(); - } - } - /* remove the source dir */ - std::fs::remove_dir_all(path)?; - } else { - let handler = |info: fs_extra::file::TransitProcess| { - info_process.copied_bytes = result + info.copied_bytes; - info_process.file_bytes_copied = info.copied_bytes; - progress_handler(info_process.clone()); - }; - - match fs_extra::file::move_file_with_progress( - path, - &destination, - &file_options, - handler, - ) { - Ok(s) => result += s, - Err(e) => { - eprintln!("{}", e); - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - format!("{}", e), - )); - } - } - } - destination.pop(); - } - Ok(result) -} diff --git a/src/fs/mod.rs b/src/fs/mod.rs index d8f8cf7..632c2ff 100644 --- a/src/fs/mod.rs +++ b/src/fs/mod.rs @@ -1,6 +1,5 @@ mod dirlist; mod entry; -pub mod fs_extra_extra; mod metadata; pub use self::dirlist::JoshutoDirList; -- cgit v1.2.3