use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use tempfile::TempDir as StdTempDir;
#[derive(Debug)]
pub struct TempDir {
inner: Option<StdTempDir>,
}
impl TempDir {
pub fn new() -> anyhow::Result<Self> {
StdTempDir::new()
.map(|inner| Self { inner: Some(inner) })
.map_err(Into::into)
}
pub fn new_in(parent: impl AsRef<Path>, prefix: impl AsRef<OsStr>) -> anyhow::Result<Self> {
StdTempDir::with_prefix_in(prefix, parent)
.map(|inner| Self { inner: Some(inner) })
.map_err(Into::into)
}
pub fn path(&self) -> &Path {
self.inner.as_ref().expect("TempDir used after drop").path()
}
#[cfg(test)]
pub fn into_path(mut self) -> PathBuf {
let inner = self.inner.take().expect("TempDir used after drop");
let path = inner.path().to_path_buf();
let _ = inner.keep();
path
}
pub fn keep(mut self) -> PathBuf {
let inner = self.inner.take().expect("TempDir used after drop");
let path = inner.path().to_path_buf();
let _ = inner.keep();
path
}
}
impl Drop for TempDir {
fn drop(&mut self) {
}
}
impl AsRef<Path> for TempDir {
fn as_ref(&self) -> &Path {
self.path()
}
}
impl Default for TempDir {
fn default() -> Self {
Self::new().expect("Failed to create temporary directory")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn tempdir_creates_and_cleans_up() {
let dir = TempDir::new().unwrap();
let path = dir.path().to_path_buf();
assert!(path.exists());
drop(dir);
}
#[test]
fn tempdir_in_parent() {
let parent = TempDir::new().unwrap();
let child = TempDir::new_in(parent.path(), "child-").unwrap();
assert!(child.path().starts_with(parent.path()));
assert!(child
.path()
.file_name()
.unwrap()
.to_string_lossy()
.starts_with("child-"));
}
#[test]
fn tempdir_into_path() {
let dir = TempDir::new().unwrap();
let path = dir.into_path();
assert!(path.exists());
}
#[test]
fn tempdir_keep() {
let dir = TempDir::new().unwrap();
let path = dir.path().to_path_buf();
dir.keep();
assert!(path.exists());
}
}