aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2023-07-29 01:43:37 +0200
committerThomas Voss <mail@thomasvoss.com> 2023-07-29 01:43:37 +0200
commitecd361e7b32fe98c2bb70efaaa7108a589213f60 (patch)
tree1fac5d89f823c18750f140fe4b5744767aa9f23f /src/main.rs
parent218e1842c001822d0a70377bff6731d4a532f598 (diff)
Copy+Delete because filesystems
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.
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs15
1 files changed, 13 insertions, 2 deletions
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<P: AsRef<Path>, Q: AsRef<Path>>(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)
+ }
+}