use crate::testing_prelude::*;
use chrono::Local;
use std::env::temp_dir;
use std::ops::Deref;
use std::sync::atomic::{AtomicU64, Ordering};
static COUNTER: AtomicU64 = AtomicU64::new(0);
pub struct TempDirectory {
path: PathBuf,
keep: bool,
}
impl TempDirectory {
#[must_use]
pub fn create(test_name: &str) -> Self {
let path = unique_path(test_name);
create_dir_all(&path).expect("Should be able to create temp dir");
Self { path, keep: false }
}
#[must_use]
pub fn keep(mut self) -> Self {
self.keep = true;
self
}
}
impl Deref for TempDirectory {
type Target = Path;
fn deref(&self) -> &Self::Target {
&self.path
}
}
impl AsRef<Path> for TempDirectory {
fn as_ref(&self) -> &Path {
&self.path
}
}
impl Drop for TempDirectory {
fn drop(&mut self) {
if !self.keep {
let _ = remove_dir_all(&self.path);
}
}
}
fn unique_path(test_name: &str) -> PathBuf {
let timestamp = Local::now().format("%Y-%m-%dT%H_%M_%S");
let counter = COUNTER.fetch_add(1, Ordering::Relaxed);
temp_dir()
.join(APP_NAME)
.join(test_name)
.join(format!("{timestamp}-{counter}"))
}