use std::{
env::{current_dir, set_current_dir},
fs::{remove_dir_all, File},
io::Write,
ops::{Deref, DerefMut},
path::{Path, PathBuf},
};
use ghee_lang::{Key, Xattr};
use tempdir::TempDir;
use crate::cmd::{idx, init, ins};
pub struct Scenario {
pub dir1: TempDirAuto,
pub dir2: TempDirAuto,
pub key1: Key,
pub key2: Key,
pub xattr1: Xattr,
pub xattr2: Xattr,
pub xattr3: Xattr,
pub xattr4: Xattr,
pub dir1path1: PathBuf,
pub dir1path2: PathBuf,
pub dir2path1: PathBuf,
pub dir2path2: PathBuf,
}
impl Scenario {
pub fn new(tag: &str) -> Self {
let prefix = format!("ghee-test-scenario-{}", tag);
let records_dir = TempDirAuto::new(format!("{}:records", prefix).as_str());
let mut records_path = records_dir.clone();
records_path.push("records.json");
{
let mut w = File::create(&records_path).unwrap();
w.write_all(
br#"{"test1": 0, "test2": 1, "test3": 2, "test4": 3}
{"test1": 10, "test2": 11, "test3": 12, "test4": 13}"#,
)
.unwrap();
}
let dir1 = TempDirAuto::new(format!("{}:1", prefix).as_str());
let dir2 = TempDirAuto::new(format!("{}:2", prefix).as_str());
let key1 = Key::from(vec!["test1"]);
let xattr1 = key1.subkeys[0].clone();
let key2 = Key::from(vec!["test2", "test3"]);
let xattr2 = key2.subkeys[0].clone();
let xattr3 = key2.subkeys[1].clone();
let xattr4 = Xattr::from("test4");
init(&dir1, &key1, false).unwrap();
idx(&dir1, Some(&dir2), &key2, false).unwrap();
ins(&dir1, &Some(records_path), false).unwrap();
let dir1path1 = {
let mut path = dir1.clone();
path.push("0");
path
};
let dir1path2 = {
let mut path = dir1.clone();
path.push("10");
path
};
let dir2path1 = {
let mut path = dir2.clone();
path.push("1");
path.push("2");
path
};
let dir2path2 = {
let mut path = dir2.clone();
path.push("11");
path.push("12");
path
};
for path in vec![&dir1path1, &dir1path2, &dir2path1, &dir2path2] {
assert!(
path.exists(),
"Path {} doesn't exist but should",
path.display()
);
}
Self {
dir1,
dir2,
key1,
key2,
xattr1,
xattr2,
xattr3,
xattr4,
dir1path1,
dir1path2,
dir2path1,
dir2path2,
}
}
}
#[derive(Debug)]
pub struct TempDirAuto {
pub dir: PathBuf,
}
impl TempDirAuto {
pub fn new(s: &str) -> Self {
Self {
dir: TempDir::new(s).unwrap().into_path(),
}
}
pub fn push<P: AsRef<Path>>(&self, p: P) -> Self {
let mut dir = self.dir.clone();
dir.push(p);
Self { dir }
}
}
impl Drop for TempDirAuto {
fn drop(&mut self) {
remove_dir_all(&self.dir).unwrap();
}
}
impl AsMut<PathBuf> for TempDirAuto {
fn as_mut(&mut self) -> &mut PathBuf {
&mut self.dir
}
}
impl AsRef<Path> for TempDirAuto {
fn as_ref(&self) -> &Path {
self.dir.as_path()
}
}
impl AsRef<PathBuf> for TempDirAuto {
fn as_ref(&self) -> &PathBuf {
&self.dir
}
}
impl Deref for TempDirAuto {
type Target = PathBuf;
fn deref(&self) -> &Self::Target {
&self.dir
}
}
impl DerefMut for TempDirAuto {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.dir
}
}
pub struct CurrentDirGuard {
pub prior_dir: PathBuf,
}
impl CurrentDirGuard {
pub fn new<P: AsRef<Path>>(alt: P) -> Self {
let alt = alt.as_ref().to_path_buf();
let prior_dir = current_dir().unwrap();
set_current_dir(&alt).unwrap();
debug_assert_eq!(current_dir().unwrap(), alt);
Self { prior_dir }
}
}
impl Drop for CurrentDirGuard {
fn drop(&mut self) {
set_current_dir(&self.prior_dir).unwrap();
}
}