//! A temporary directory for a test, removed with everything in it when the value is dropped //! (tip T44). Included with `#[path = "support/temp.rs"] mod temp;`. #![allow(dead_code)] // each test file uses a different part of this module use std::ffi::OsStr; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicU32, Ordering}; static NEXT: AtomicU32 = AtomicU32::new(0); pub struct TempDir(PathBuf); impl TempDir { /// A fresh, empty directory `/--`. pub fn new(tag: &str) -> TempDir { let n = NEXT.fetch_add(1, Ordering::SeqCst); let path = std::env::temp_dir().join(format!("{tag}-{}-{n}", std::process::id())); let _ = std::fs::remove_dir_all(&path); std::fs::create_dir_all(&path).unwrap(); TempDir(path) } } impl Deref for TempDir { type Target = Path; fn deref(&self) -> &Path { &self.0 } } impl AsRef for TempDir { fn as_ref(&self) -> &Path { &self.0 } } impl AsRef for TempDir { fn as_ref(&self) -> &OsStr { self.0.as_os_str() } } impl Drop for TempDir { fn drop(&mut self) { // Put back the permissions a test may have taken away, or the removal fails. use std::os::unix::fs::PermissionsExt; let _ = std::fs::set_permissions(&self.0, std::fs::Permissions::from_mode(0o700)); let _ = std::fs::remove_dir_all(&self.0); } }