diff options
author | Thomas Voss <mail@thomasvoss.com> | 2023-07-29 01:43:37 +0200 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2023-07-29 01:43:37 +0200 |
commit | ecd361e7b32fe98c2bb70efaaa7108a589213f60 (patch) | |
tree | 1fac5d89f823c18750f140fe4b5744767aa9f23f /src/main.rs | |
parent | 218e1842c001822d0a70377bff6731d4a532f598 (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.rs | 15 |
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) + } +} |