more refactoring + interpret EDITOR variable
This commit is contained in:
parent
c3a8ade31a
commit
11ce644fca
2 changed files with 30 additions and 29 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::io::{ErrorKind, BufRead, BufReader};
|
use std::io::{ErrorKind, Write, BufRead, BufReader};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use rand::distributions::{Alphanumeric, DistString};
|
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> {
|
pub fn move_to(&mut self, target_list: &DirList) -> Result<(), String> {
|
||||||
let src_len = self.entries.len();
|
let src_len = self.entries.len();
|
||||||
let mut intermediate_files: HashMap<String, String> = HashMap::new();
|
let mut intermediate_files: HashMap<String, String> = 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 {
|
for i in 0..src_len {
|
||||||
if self.entries[i] != target_list.entries[i] {
|
if self.entries[i] != target_list.entries[i] {
|
||||||
// is the destination already in the source list?
|
// is the destination already in the source list?
|
||||||
// if so, an intermediate file is needed
|
// 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==&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());
|
intermediate_files.insert(unique.clone(), target_list.entries[i].clone());
|
||||||
fs::rename(&self.entries[i], &unique).expect("failed to rename file");
|
fs::rename(&self.entries[i], &unique).expect("failed to rename file");
|
||||||
println!("Moving {} -> {}", self.entries[i], unique);
|
println!("Moving {} -> {}", self.entries[i], unique);
|
||||||
|
|
@ -87,17 +98,17 @@ impl DirList {
|
||||||
Ok(())
|
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);
|
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() {
|
while target_list.entries.iter().any(|j| j==&string) || Path::new(&string).is_file() {
|
||||||
string = Alphanumeric.sample_string(&mut rand::thread_rng(), 16);
|
string = Alphanumeric.sample_string(&mut rand::thread_rng(), 16);
|
||||||
}
|
}
|
||||||
string
|
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
|
// Make sure there are an equal number of sources and destinations
|
||||||
if self.entries.len() != target_list.entries.len() {
|
if self.entries.len() != target_list.entries.len() {
|
||||||
return Err("ERROR: Source and target list don't have the same number of
|
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());
|
return Err("ERROR: You can't move to empty names.".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure all destination files are unique
|
// Make sure all destination files are unique in target_list
|
||||||
if target_list.entries.len() != target_list.unique_length() {
|
let unique_entries = target_list.entries.iter().map(|x| (x, x)).collect::<HashMap<_, _>>();
|
||||||
|
if target_list.entries.len() != unique_entries.len() {
|
||||||
let doubles = self.show_doubles(&target_list);
|
let doubles = self.show_doubles(&target_list);
|
||||||
let error = format!("ERROR: You're trying to move multiple files to the same name.\n{}", doubles);
|
let error = format!("ERROR: You're trying to move multiple files to the same name.\n{}", doubles);
|
||||||
return Err(error);
|
return Err(error);
|
||||||
|
|
@ -118,12 +130,6 @@ impl DirList {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unique_length(&self) -> usize {
|
|
||||||
let map = self.entries.iter().map(|x| (x, x)).collect::<HashMap<_, _>>();
|
|
||||||
map.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn show_doubles(&self, target_list: &DirList) -> String {
|
fn show_doubles(&self, target_list: &DirList) -> String {
|
||||||
let mut paths = HashMap::new();
|
let mut paths = HashMap::new();
|
||||||
let mut doubles = String::new();
|
let mut doubles = String::new();
|
||||||
|
|
|
||||||
25
src/main.rs
25
src/main.rs
|
|
@ -2,10 +2,10 @@ mod dirlist;
|
||||||
|
|
||||||
pub use crate::dirlist::*;
|
pub use crate::dirlist::*;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::io::Write;
|
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
|
|
@ -34,12 +34,8 @@ fn unlock_dir() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_temp_file(paths: &Vec<String>) -> String {
|
fn create_temp_file() -> String {
|
||||||
let mut tmpfile = NamedTempFile::with_suffix(".mvwrap").expect("Could not create tempfile");
|
let tmpfile = NamedTempFile::with_suffix(".mvwrap").expect("Could not create tempfile");
|
||||||
|
|
||||||
for path in paths {
|
|
||||||
let _ = writeln!(tmpfile, "{}", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
let filepath = tmpfile.path().display().to_string();
|
let filepath = tmpfile.path().display().to_string();
|
||||||
|
|
||||||
|
|
@ -55,14 +51,16 @@ fn remove_temp_file(tmpfile: &String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn edit_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)
|
.arg(tmpfile)
|
||||||
.status()
|
.status()
|
||||||
.expect("failed to execute editor process");
|
.expect("failed to execute editor process");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Place lockfile to not have multiple mvw processes running in the same dir at the same time
|
// Place lockfile to not have multiple mvw processes running in the same dir at the same time
|
||||||
lock_dir();
|
lock_dir();
|
||||||
|
|
@ -72,9 +70,8 @@ fn main() {
|
||||||
let mut source_list = DirList::from_current_dir();
|
let mut source_list = DirList::from_current_dir();
|
||||||
|
|
||||||
// create named tempfile and fill with paths
|
// create named tempfile and fill with paths
|
||||||
let temp_file = create_temp_file(&source_list.entries);
|
let temp_file = create_temp_file();
|
||||||
|
source_list.to_file(&temp_file);
|
||||||
//display_temp_file(&temp_file);
|
|
||||||
|
|
||||||
edit_temp_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!)
|
// (also don't overwrite existing files that are not in the input list!)
|
||||||
|
|
||||||
//display_temp_file(&temp_file);
|
|
||||||
|
|
||||||
remove_temp_file(&temp_file);
|
remove_temp_file(&temp_file);
|
||||||
unlock_dir();
|
unlock_dir();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue