use std::ffi::OsStr;
use std::path;
use super::errors::FixtureError;
use super::errors::FixtureKind;
use super::errors::ResultChainExt;
#[derive(Debug)]
pub struct TempDir {
temp: Inner,
}
#[derive(Debug)]
enum Inner {
Temp(tempfile::TempDir),
Persisted(path::PathBuf),
}
impl TempDir {
pub fn new() -> Result<Self, FixtureError> {
let temp = tempfile::TempDir::new().chain(FixtureError::new(FixtureKind::CreateDir))?;
let temp = Inner::Temp(temp);
Ok(Self { temp })
}
pub fn new_in<P: AsRef<path::Path>>(dir: P) -> Result<Self, FixtureError> {
let temp =
tempfile::TempDir::new_in(dir).chain(FixtureError::new(FixtureKind::CreateDir))?;
let temp = Inner::Temp(temp);
Ok(Self { temp })
}
pub fn with_prefix<S: AsRef<OsStr>>(prefix: S) -> Result<Self, FixtureError> {
let temp = tempfile::TempDir::with_prefix(prefix)
.chain(FixtureError::new(FixtureKind::CreateDir))?;
let temp = Inner::Temp(temp);
Ok(Self { temp })
}
pub fn with_prefix_in<S: AsRef<OsStr>, P: AsRef<path::Path>>(
prefix: S,
dir: P,
) -> Result<Self, FixtureError> {
let temp = tempfile::TempDir::with_prefix_in(prefix, dir)
.chain(FixtureError::new(FixtureKind::CreateDir))?;
let temp = Inner::Temp(temp);
Ok(Self { temp })
}
pub fn into_persistent_if(self, yes: bool) -> Self {
if !yes {
return self;
}
self.into_persistent()
}
pub fn into_persistent(self) -> Self {
let path = match self.temp {
Inner::Temp(temp) => temp.into_path(),
Inner::Persisted(path) => path,
};
let temp = Inner::Persisted(path);
Self { temp }
}
pub fn path(&self) -> &path::Path {
match self.temp {
Inner::Temp(ref temp) => temp.path(),
Inner::Persisted(ref path) => path.as_path(),
}
}
pub fn close(self) -> Result<(), FixtureError> {
match self.temp {
Inner::Temp(temp) => temp
.close()
.chain(FixtureError::new(FixtureKind::Cleanup))?,
Inner::Persisted(_) => (),
}
Ok(())
}
}
impl AsRef<path::Path> for TempDir {
fn as_ref(&self) -> &path::Path {
self.path()
}
}
impl std::ops::Deref for TempDir {
type Target = path::Path;
#[inline]
fn deref(&self) -> &path::Path {
self.path()
}
}