rust/crates/rust-analyzer/tests/slow-tests/testdir.rs
2021-05-17 19:01:54 +03:00

63 lines
1.4 KiB
Rust

use std::{
fs, io,
path::{Path, PathBuf},
sync::atomic::{AtomicUsize, Ordering},
};
pub(crate) struct TestDir {
path: PathBuf,
keep: bool,
}
impl TestDir {
pub(crate) fn new() -> TestDir {
let base = std::env::temp_dir().join("testdir");
let pid = std::process::id();
static CNT: AtomicUsize = AtomicUsize::new(0);
for _ in 0..100 {
let cnt = CNT.fetch_add(1, Ordering::Relaxed);
let path = base.join(format!("{}_{}", pid, cnt));
if path.is_dir() {
continue;
}
fs::create_dir_all(&path).unwrap();
return TestDir { path, keep: false };
}
panic!("Failed to create a temporary directory")
}
#[allow(unused)]
pub(crate) fn keep(mut self) -> TestDir {
self.keep = true;
self
}
pub(crate) fn path(&self) -> &Path {
&self.path
}
}
impl Drop for TestDir {
fn drop(&mut self) {
if self.keep {
return;
}
remove_dir_all(&self.path).unwrap()
}
}
#[cfg(not(windows))]
fn remove_dir_all(path: &Path) -> io::Result<()> {
fs::remove_dir_all(path)
}
#[cfg(windows)]
fn remove_dir_all(path: &Path) -> io::Result<()> {
for _ in 0..99 {
if fs::remove_dir_all(path).is_ok() {
return Ok(());
}
std::thread::sleep(std::time::Duration::from_millis(10))
}
fs::remove_dir_all(path)
}