1use std::fs;
2use std::path::{Path, PathBuf};
3
4pub struct EphemeralDir {
5 path: PathBuf,
7}
8
9impl EphemeralDir {
10 pub fn new(path: impl AsRef<Path>) -> eyre::Result<Self> {
11 let path = path.as_ref();
12 assert!(!path.exists());
13
14 fs::create_dir_all(path)?;
15
16 Ok(Self {
17 path: PathBuf::from(path),
18 })
19 }
20
21 pub fn new_forced(path: impl AsRef<Path>) -> eyre::Result<Self> {
22 let path = path.as_ref();
23 if path.exists() {
24 fs::remove_dir_all(path)?;
25 }
26
27 Self::new(path)
28 }
29
30 pub fn path(&self) -> &Path {
31 self.path.as_ref()
32 }
33}
34
35impl Drop for EphemeralDir {
36 fn drop(&mut self) {
37 let _ = fs::remove_dir_all(self.path());
38 }
39}
40
41#[test]
42fn test_dir_exists_after_creation() {
43 let path = "/tmp/ephemeral_dir_test";
44 let res_dir = EphemeralDir::new_forced(path);
45 assert!(res_dir.is_ok());
46 let Ok(dir) = res_dir else { unreachable!() };
47 assert!(dir.path().exists());
48 let dir_path_str = format!("{}", dir.path().display());
49 assert_eq!(dir_path_str, path);
50}
51
52#[test]
53fn test_dir_does_not_exist_after_going_out_of_scope() {
54 let path = "/tmp/ephemeral_dir_test";
55 let res_dir = EphemeralDir::new_forced(path);
56 assert!(res_dir.is_ok());
57 {
58 let Ok(dir) = res_dir else { unreachable!() };
59 assert!(dir.path().exists());
60 let dir_path_str = format!("{}", dir.path().display());
61 assert_eq!(dir_path_str, path);
62 let dir_path = Path::new(&dir_path_str);
63 assert!(dir_path.exists());
64 }
65 let path_path = Path::new(path);
66 assert!(!path_path.exists());
67}