diff --git a/src/dirlist.rs b/src/dirlist.rs index 1593acb..2896581 100644 --- a/src/dirlist.rs +++ b/src/dirlist.rs @@ -1,7 +1,7 @@ use std::fs; use std::fs::File; use std::path::{Path, PathBuf}; -use std::io::{ErrorKind, BufRead, BufReader}; +use std::io::{ErrorKind, Write, BufRead, BufReader}; use std::collections::HashMap; use rand::distributions::{Alphanumeric, DistString}; @@ -59,18 +59,29 @@ impl DirList { } } + pub fn to_file(&self, target_file: &String) { + let mut file = File::create(target_file).expect("no such file"); + + for entry in &self.entries { + writeln!(file, "{}", entry).expect("Unable to write to file"); + } + } + pub fn move_to(&mut self, target_list: &DirList) -> Result<(), String> { let src_len = self.entries.len(); let mut intermediate_files: HashMap = HashMap::new(); - self.run_checks(&target_list)?; + self.run_basic_checks(&target_list)?; + if ! self.safe_source { + println!("Implement check if target files already exist"); + } for i in 0..src_len { if self.entries[i] != target_list.entries[i] { // is the destination already in the source list? // if so, an intermediate file is needed if self.entries.iter().any(|j| j==&target_list.entries[i]) { - let unique = Self::unique_entry(&target_list); + let unique = Self::get_unique_entry(&target_list); intermediate_files.insert(unique.clone(), target_list.entries[i].clone()); fs::rename(&self.entries[i], &unique).expect("failed to rename file"); println!("Moving {} -> {}", self.entries[i], unique); @@ -87,17 +98,17 @@ impl DirList { Ok(()) } - fn unique_entry(target_list: &DirList) -> String { + fn get_unique_entry(target_list: &DirList) -> String { let mut string = Alphanumeric.sample_string(&mut rand::thread_rng(), 16); - // Generate unique name that does not exist in dir and is not in dst_paths + // Generate unique name that does not exist in current dir and is not in target_list while target_list.entries.iter().any(|j| j==&string) || Path::new(&string).is_file() { string = Alphanumeric.sample_string(&mut rand::thread_rng(), 16); } string } - fn run_checks(&self, target_list: &DirList) -> Result<(), String> { + fn run_basic_checks(&self, target_list: &DirList) -> Result<(), String> { // Make sure there are an equal number of sources and destinations if self.entries.len() != target_list.entries.len() { return Err("ERROR: Source and target list don't have the same number of @@ -109,8 +120,9 @@ impl DirList { return Err("ERROR: You can't move to empty names.".to_string()); } - // Make sure all destination files are unique - if target_list.entries.len() != target_list.unique_length() { + // Make sure all destination files are unique in target_list + let unique_entries = target_list.entries.iter().map(|x| (x, x)).collect::>(); + if target_list.entries.len() != unique_entries.len() { let doubles = self.show_doubles(&target_list); let error = format!("ERROR: You're trying to move multiple files to the same name.\n{}", doubles); return Err(error); @@ -118,12 +130,6 @@ impl DirList { Ok(()) } - fn unique_length(&self) -> usize { - let map = self.entries.iter().map(|x| (x, x)).collect::>(); - map.len() - } - - fn show_doubles(&self, target_list: &DirList) -> String { let mut paths = HashMap::new(); let mut doubles = String::new(); diff --git a/src/main.rs b/src/main.rs index f18df08..09d1034 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,10 +2,10 @@ mod dirlist; pub use crate::dirlist::*; +use std::env; use std::fs; use std::fs::File; use std::path::Path; -use std::io::Write; use std::process; use std::process::Command; use tempfile::NamedTempFile; @@ -34,12 +34,8 @@ fn unlock_dir() { } } -fn create_temp_file(paths: &Vec) -> String { - let mut tmpfile = NamedTempFile::with_suffix(".mvwrap").expect("Could not create tempfile"); - - for path in paths { - let _ = writeln!(tmpfile, "{}", path); - } +fn create_temp_file() -> String { + let tmpfile = NamedTempFile::with_suffix(".mvwrap").expect("Could not create tempfile"); let filepath = tmpfile.path().display().to_string(); @@ -55,14 +51,16 @@ fn remove_temp_file(tmpfile: &String) { } fn edit_temp_file(tmpfile: &String) { - let _output = Command::new("vi") + let editor = match env::var("EDITOR") { + Ok(e) => e, + Err(_) => "vi".to_string(), + }; + let _output = Command::new(editor) .arg(tmpfile) .status() .expect("failed to execute editor process"); - } - fn main() { // Place lockfile to not have multiple mvw processes running in the same dir at the same time lock_dir(); @@ -72,9 +70,8 @@ fn main() { let mut source_list = DirList::from_current_dir(); // create named tempfile and fill with paths - let temp_file = create_temp_file(&source_list.entries); - - //display_temp_file(&temp_file); + let temp_file = create_temp_file(); + source_list.to_file(&temp_file); edit_temp_file(&temp_file); @@ -103,8 +100,6 @@ fn main() { // (also don't overwrite existing files that are not in the input list!) - //display_temp_file(&temp_file); - remove_temp_file(&temp_file); unlock_dir(); }