I need a destination temporary file for copying. The tempfile docs isn't big on examples; there is nothing similar to what I really want. This is a snippet of pseudocode I'd like to implement:
let tmp = tempfile:: ???; // Would be great to specify .ext, too.
let tmp_path = tmp.path();
tmp.close();
fs::copy(src_path, tmp_path).expect( ... );
modify(tmp_path); // It's brief, third party and wants a closed file.
fs::copy(tmp_path, dst_path).expect( ... );
tmp.remove();
For setting an extension - use the Builder and in particular, the suffix method to set the extension.
As for a "closed" file, I am assuming you're working on Windows, because on modern Unix environments, multiple programs can read and write to the same file simultaneously. Now the way tempfile crate works is that, when you drop the handle, the file is closed and removed. So if you call close, then the file will probably be deleted. The path will probably be still be valid. So you can still probably pass it.
On unix file system single file can be accessed from zero, one or many paths. It seems what you want is some tmp path, not the file itself. fs::copy() doesn't require the dst file exist.
You can make temp path via making tempdir() and append some fixed filename after its path.
This is a classic security hole on unixy systems. In between the copying back and forth the file could be replaced by another user. Instead of st::fs::copy, use std::io::copy with the opened file.
The only reason to do what you're asking would be if you need to pass the temporary filename to another program that won't accept it on stdin or stdout. If that's what you're needing to do, then you need a temporary directory.
If you're writing windows-only code, however, I have know clue what advice you should take.
Tbh, I don't really understand the requirements here. How can modify require a closed file? Anything could open the file and you'd be none the wiser unless they lock it in some way.
I tried a temporary directory. Something's wrong, though one cannot tell what right away:
hread 'main' panicked at '🔹Error while copying "/home/alexey/common/Downloads/UpDown/Books/Audio/Vladimir Nabokov - Ada, or ardor (1969)/Disc 1/01 Track 1.mp3" to "/tmp/.tmphqLiSS/tmpaudio.mp3".🔹: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/main.rs:578:34
stack backtrace:
0: rust_begin_unwind
at /rustc/5531927e8af9b99ad923af4c827c91038bca51ee/library/std/src/panicking.rs:498:5
1: core::panicking::panic_fmt
at /rustc/5531927e8af9b99ad923af4c827c91038bca51ee/library/core/src/panicking.rs:107:14
2: core::result::unwrap_failed
at /rustc/5531927e8af9b99ad923af4c827c91038bca51ee/library/core/src/result.rs:1661:5
3: procrustes::GlobalState::track_copy::file_copy
4: procrustes::GlobalState::album_copy
5: procrustes::main
The paths look quite plausible, just as I expected. The code looks like this:
this code is the issue. tmp_dir.unwrap() moves tmp_dir. Once the expression tmp_dir.unwrap().path().join(format!("tmpaudio.{}", ext.to_str().unwrap())) finishes the TempDir value gets dropped which removes the temporary directory. You can fix it by doing the unwrap before assigning to tmp_dir:
let tmp_dir = TempDir::new().unwrap();
let tmp = tmp_dir
.path()
.join(format!("tmpaudio.{}", ext.to_str().unwrap()));