From f723136fd3b1483ad4f81b5f8e202370758371a6 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Fri, 4 Nov 2022 14:59:29 +0100 Subject: Create a working implementation --- src/main.rs | 68 +++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 5325175..8439302 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,18 +5,22 @@ mod main_result; use std::{ collections::HashSet, env, + fs, hash::Hash, io::{self, BufRead, BufReader, BufWriter, Write, Seek, SeekFrom}, + path::Path, process::Command }; -use encoded_string::*; -use error::*; -use main_result::*; +use { + encoded_string::EncodedString, + error::Error, + main_result::MainResult +}; use { itertools::Itertools, - tempfile::NamedTempFile + tempfile::{Builder, NamedTempFile, TempDir} }; fn main() -> MainResult { @@ -24,8 +28,8 @@ fn main() -> MainResult { } fn work() -> Result<(), Error> { - let files = env::args().skip(1).collect::>(); - let dups = duplicate_elements(files.clone()); + let old_files = env::args().skip(1).collect::>(); + let dups = duplicate_elements(old_files.clone()); if !dups.is_empty() { return Err(Error::DuplicateElems(dups)); } @@ -33,7 +37,7 @@ fn work() -> Result<(), Error> { let mut tmpfile = NamedTempFile::new()?; let mut writer = BufWriter::new(&tmpfile); - files.iter().try_for_each(|f| encode_to_file(&mut writer, f))?; + old_files.iter().try_for_each(|f| encode_to_file(&mut writer, f))?; writer.flush()?; drop(writer); @@ -49,27 +53,29 @@ fn work() -> Result<(), Error> { .wait()?; tmpfile.seek(SeekFrom::Start(0))?; - let new_files = decode_from_file(&tmpfile)?; - assert_changes( - files.iter().cloned().collect(), - new_files.iter().cloned().collect() - )?; - new_files.iter().for_each(|f| println!("{}", f)); - - Ok(()) -} - -fn assert_changes(old: Vec, new: Vec) -> Result<(), Error> { - if old.len() != new.len() { + let new_files = decode_from_file(&tmpfile)?; + if old_files.len() != new_files.len() { return Err(Error::BadLengths); } - let dups = duplicate_elements(new); + let dups = duplicate_elements(new_files.iter().cloned().collect::>()); if !dups.is_empty() { return Err(Error::DuplicateElems(dups)); } + let tmpdir = Builder::new().prefix("mmv").tempdir()?; + let mut conflicts = Vec::<&str>::new(); + + old_files + .iter() + .zip(new_files.iter()) + .filter(|(x, y)| x != y) + .try_for_each(|(x, y)| try_move(&mut conflicts, &tmpdir, x, y))?; + conflicts + .iter() + .try_for_each(|c| do_move(&tmpdir, c))?; + Ok(()) } @@ -109,3 +115,25 @@ fn decode_from_file(tmpfile: &NamedTempFile) -> Result, io::Error> { }) .collect::, _>>() } + +fn try_move<'a>( + conflicts: &mut Vec<&'a str>, + tmpdir: &TempDir, + old: &str, + new: &'a str +) -> Result<(), io::Error> { + if Path::new(new).exists() { + let new_loc = tmpdir.path().to_str().unwrap().to_owned() + new; + fs::rename(old, new_loc)?; + conflicts.push(new); + } else { + fs::rename(old, new)?; + } + Ok(()) +} + +fn do_move(tmpdir: &TempDir, new: &str) -> Result<(), io::Error> { + let old = tmpdir.path().to_str().unwrap().to_owned() + new; + fs::rename(old, new)?; + Ok(()) +} -- cgit v1.2.3