diff --git a/Cargo.lock b/Cargo.lock index 5a7bdfd..967408c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,7 +206,7 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "mvw" -version = "0.1.4" +version = "0.1.5" dependencies = [ "clap", "dialoguer", diff --git a/src/dirlist.rs b/src/dirlist.rs index 2c748bd..d33bd1d 100644 --- a/src/dirlist.rs +++ b/src/dirlist.rs @@ -7,11 +7,25 @@ use rand::distributions::{Alphanumeric, DistString}; const LOCK_FILE: &str = ".mvwrap"; +enum DirListEntry { + Path(PathBuf), + Text(String) +} + +impl ToString for DirListEntry { + fn to_string(&self) -> String { + match self { + DirListEntry::Text(line) => line.clone(), + DirListEntry::Path(path) => path.display().to_string(), + } + } +} + pub struct DirList { safe_source: bool, noop: bool, verbose: bool, - entries: Vec, + entries: Vec, } impl DirList { @@ -24,14 +38,15 @@ impl DirList { .collect() }; - let mut path_list : Vec = vec![]; + let mut path_list : Vec = vec![]; for path in paths { let path_string = path.display().to_string(); if path_string != format!("./{}", LOCK_FILE) { - path_list.push(path_string[2..].to_string()); + path_list.push(DirListEntry::Path(path)); } } - path_list.sort(); + // This sort is probably not /really/ needed, but just nice + //path_list.sort(); Self { safe_source: true, @@ -45,7 +60,7 @@ impl DirList { let file = File::open(src_file).expect("no such file"); let buf = BufReader::new(file); let lines = buf.lines() - .map(|l| l.expect("Could not parse line")) + .map(|l| DirListEntry::Text(l.expect("Could not parse line"))) .collect(); Self { @@ -61,7 +76,7 @@ impl DirList { safe_source: false, noop: false, verbose: false, - entries: list.to_vec(), + entries: list.iter().map(|l| DirListEntry::Text(l.to_string())).collect(), } } @@ -77,7 +92,10 @@ impl DirList { 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"); + match entry { + DirListEntry::Text(line) => writeln!(file, "{}", line).expect("Unable to write to file"), + DirListEntry::Path(path) => writeln!(file, "{}", path.display().to_string()).expect("Unable to write to file"), + } } } @@ -91,17 +109,27 @@ impl DirList { } for i in 0..src_len { - if self.entries[i] != target_list.entries[i] { + if self.entries[i].to_string() != target_list.entries[i].to_string() { // 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]) { + if self.entries.iter().any(|j| j.to_string() == target_list.entries[i].to_string()) { let unique = Self::get_unique_entry(target_list); - intermediate_files.insert(unique.clone(), target_list.entries[i].clone()); - if ! self.noop { fs::rename(&self.entries[i], &unique).expect("failed to rename file"); } - if self.verbose { println!("Moving {} -> {}", self.entries[i], unique); } + intermediate_files.insert(unique.clone(), target_list.entries[i].to_string().clone()); + if ! self.noop { + match &self.entries[i] { + DirListEntry::Text(name) => fs::rename(name.to_string(), &unique).expect("failed to rename file"), + DirListEntry::Path(path) => fs::rename(path.as_path(), &unique).expect("failed to rename file"), + } + } + if self.verbose { println!("Moving {} -> {}", self.entries[i].to_string(), unique); } } else { - if ! self.noop { fs::rename(&self.entries[i], &target_list.entries[i]).expect("failed to rename file"); } - if self.verbose { println!("Moving {} -> {}", self.entries[i], target_list.entries[i]); } + if ! self.noop { + match &self.entries[i] { + DirListEntry::Text(name) => fs::rename(name.to_string(), &target_list.entries[i].to_string()).expect("failed to rename file"), + DirListEntry::Path(path) => fs::rename(path.as_path(), &target_list.entries[i].to_string()).expect("failed to rename file"), + } + } + if self.verbose { println!("Moving {} -> {}", self.entries[i].to_string(), target_list.entries[i].to_string()); } } } } @@ -116,7 +144,7 @@ impl DirList { let mut string = Alphanumeric.sample_string(&mut rand::thread_rng(), 16); // 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() { + while target_list.entries.iter().any(|j| j.to_string() == string) || Path::new(&string).is_file() { string = Alphanumeric.sample_string(&mut rand::thread_rng(), 16); } string @@ -130,12 +158,12 @@ impl DirList { } // Make sure destination names are not empty - if target_list.entries.iter().any(|i| i.is_empty()) { + if target_list.entries.iter().any(|i| i.to_string().is_empty()) { return Err("ERROR: You can't move to empty names.".to_string()); } // Make sure all destination files are unique in target_list - let unique_entries = target_list.entries.iter().map(|x| (x, x)).collect::>(); + let unique_entries = target_list.entries.iter().map(|x| (x.to_string(), x.to_string())).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); @@ -148,15 +176,16 @@ impl DirList { let mut paths = HashMap::new(); let mut doubles = String::new(); - for (i, _) in target_list.entries.iter().enumerate() { - paths.entry(&target_list.entries[i]).or_insert(Vec::new()); - paths.get_mut(&target_list.entries[i]).unwrap().push(i); + for (linenr, _) in target_list.entries.iter().enumerate() { + let path_name = target_list.entries[linenr].to_string().clone(); + paths.entry(target_list.entries[linenr].to_string()).or_insert(Vec::new()); + paths.get_mut(&path_name).unwrap().push(linenr); } for (path, lines) in paths.iter() { if lines.len() > 1 { for i in lines.iter() { - doubles = format!("{doubles}\n[line: {}] {} -> {}", i+1, self.entries[*i], path); + doubles = format!("{doubles}\n[line: {}] {} -> {}", i+1, self.entries[*i].to_string(), path); } doubles = format!("{doubles}\n"); }