use std::path::{Path, PathBuf};
#[macro_export]
macro_rules! err {
($($tt:tt)*) => {
Box::<dyn std::error::Error>::from(format!($($tt)*))
}
}
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[derive(Debug)]
pub struct TestContext {
_tmpdir: TempDir,
data_dir: PathBuf,
index_dir: PathBuf,
}
impl TestContext {
pub fn new(name: &str) -> TestContext {
let tmpdir = TempDir::new("imdb-rename-test-index").unwrap();
let data_dir = PathBuf::from("../data/test").join(name);
let index_dir = tmpdir.path().to_path_buf();
TestContext { _tmpdir: tmpdir, data_dir, index_dir }
}
pub fn data_dir(&self) -> &Path {
&self.data_dir
}
pub fn index_dir(&self) -> &Path {
&self.index_dir
}
}
#[derive(Debug)]
pub struct TempDir(PathBuf);
impl Drop for TempDir {
fn drop(&mut self) {
std::fs::remove_dir_all(&self.0).unwrap();
}
}
impl TempDir {
pub fn new(prefix: &str) -> Result<TempDir> {
use std::sync::atomic::{AtomicUsize, Ordering};
static TRIES: usize = 100;
static COUNTER: AtomicUsize = AtomicUsize::new(0);
let tmpdir = std::env::temp_dir();
for _ in 0..TRIES {
let count = COUNTER.fetch_add(1, Ordering::SeqCst);
let path = tmpdir.join(prefix).join(count.to_string());
if path.is_dir() {
continue;
}
std::fs::create_dir_all(&path).map_err(|e| {
err!("failed to create {}: {}", path.display(), e)
})?;
return Ok(TempDir(path));
}
Err(err!("failed to create temp dir after {} tries", TRIES))
}
pub fn path(&self) -> &Path {
&self.0
}
}