45 lines
1.2 KiB
Rust
45 lines
1.2 KiB
Rust
use std::fs;
|
|
use std::path::{Path, PathBuf};
|
|
use std::sync::atomic::{AtomicU64, Ordering};
|
|
|
|
pub struct TemporaryDirectory(PathBuf);
|
|
|
|
impl TemporaryDirectory {
|
|
pub fn new() -> Self {
|
|
Self::new_in(&std::env::temp_dir())
|
|
}
|
|
|
|
pub fn new_in(parent: &Path) -> Self {
|
|
static NEXT: AtomicU64 = AtomicU64::new(0);
|
|
loop {
|
|
let path = parent.join(format!(
|
|
"dever-core-test-{}-{}",
|
|
std::process::id(),
|
|
NEXT.fetch_add(1, Ordering::Relaxed)
|
|
));
|
|
let mut builder = fs::DirBuilder::new();
|
|
#[cfg(unix)]
|
|
{
|
|
use std::os::unix::fs::DirBuilderExt;
|
|
builder.mode(0o700);
|
|
}
|
|
match builder.create(&path) {
|
|
Ok(()) => return Self(path),
|
|
Err(error) if error.kind() == std::io::ErrorKind::AlreadyExists => continue,
|
|
Err(error) => panic!("cannot create test directory: {error}"),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn path(&self) -> &Path {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl Drop for TemporaryDirectory {
|
|
fn drop(&mut self) {
|
|
// This object owns only the directory it exclusively created above.
|
|
let _ = fs::remove_dir_all(&self.0);
|
|
}
|
|
}
|