use std::cell::Cell;
use std::collections::HashSet;
use std::ffi::OsStr;
use std::fs;
use std::path::PathBuf;
use std::thread::current;
use std::time::{SystemTime, UNIX_EPOCH};
pub(crate) struct TestsDb(u64, HashSet<PathBuf>);
thread_local! {
static TESTS_COUNTER: Cell<u64> = Cell::new(1);
}
impl TestsDb {
pub(crate) fn new() -> Self {
let duration = SystemTime::now().duration_since(UNIX_EPOCH);
let postfix = match duration {
Ok(dur) => dur.as_secs(),
Err(_) => 0,
};
Self(postfix, HashSet::new())
}
pub(crate) unsafe fn build_temporary_db_name(&mut self, path_buf: PathBuf) -> PathBuf {
let basename = path_buf.file_stem().unwrap_or_else(|| OsStr::new("db"));
let current_thread_local_count = TESTS_COUNTER.get();
TESTS_COUNTER.set(current_thread_local_count + 1);
let mut new_filename = basename.to_os_string();
new_filename.push(format!(
"_{}_{:?}_{}",
self.0,
current().id(),
current_thread_local_count
));
new_filename.push(
path_buf
.extension()
.map(|str| format!(".{}", str.to_string_lossy().to_string()))
.unwrap_or_default(),
);
let new_buf = path_buf.with_file_name(new_filename);
self.1.insert(new_buf.clone());
new_buf
}
pub(crate) fn tear_down(&self) {
self.1.iter().for_each(|path| {
fs::remove_file(path).unwrap_or_else(|why| println!("Teardown: {}", why))
})
}
}