From ecd361e7b32fe98c2bb70efaaa7108a589213f60 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Sat, 29 Jul 2023 01:43:37 +0200 Subject: Copy+Delete because filesystems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns out that ‘fs::rename()’ calls ‘rename(2)’ under the hood. This is a problem because the temporary directory we use is typically located on a different filesystem than your home directory for example, and so this would fail. The shitty workaround here is to copy the files and then delete them. But it just keeps getting better! Turns out that despite the fact that ‘everything is a file’ on *NIX, we cannot just call ‘fs::copy()’ or ‘fs::remove_file()’ on directories; that would be too smart. --- src/main.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 9bbe39f..24bd8f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -139,7 +139,7 @@ fn work() -> Result<(), Error> { if flags.dryrun { println!("{} -> {}", s.as_path().display(), dst.as_path().display()); } else { - fs::rename(s, &dst)?; + copy_and_remove_file_or_dir(&s, &dst)?; } *s_d = (dst, d.to_path_buf()) @@ -149,7 +149,7 @@ fn work() -> Result<(), Error> { if flags.dryrun { println!("{} -> {}", s.as_path().display(), d.as_path().display()); } else { - fs::rename(s, d)?; + copy_and_remove_file_or_dir(&s, &d)?; } } @@ -253,3 +253,14 @@ fn normalize_path(path: &Path) -> PathBuf { } ret } + +fn copy_and_remove_file_or_dir, Q: AsRef>(from: P, to: Q) -> io::Result<()> { + let data = fs::metadata(&from)?; + if data.is_dir() { + fs::create_dir(&to)?; + fs::remove_dir(&from) + } else { + fs::copy(&from, &to)?; + fs::remove_file(&from) + } +} -- cgit v1.2.3