1use std::fs;
2use std::path::{Path, PathBuf};
3
4pub fn ephemeral_dir(path: impl AsRef<Path>) -> eyre::Result<EphemeralDir> {
5 EphemeralDir::new(path)
6}
7
8pub fn ephemeral_dir_forced(path: impl AsRef<Path>) -> eyre::Result<EphemeralDir> {
9 EphemeralDir::new_forced(path)
10}
11
12pub struct EphemeralDir {
13 path: PathBuf,
15}
16
17impl EphemeralDir {
18 pub fn new(path: impl AsRef<Path>) -> eyre::Result<Self> {
19 let path = path.as_ref();
20 assert!(!path.exists());
21
22 fs::create_dir_all(path)?;
23
24 Ok(Self {
25 path: PathBuf::from(path),
26 })
27 }
28
29 pub fn new_forced(path: impl AsRef<Path>) -> eyre::Result<Self> {
30 let path = path.as_ref();
31 if path.exists() {
32 fs::remove_dir_all(path)?;
33 }
34
35 Self::new(path)
36 }
37
38 pub fn path(&self) -> &Path {
39 self.path.as_ref()
40 }
41}
42
43impl Drop for EphemeralDir {
44 fn drop(&mut self) {
45 let _ = fs::remove_dir_all(self.path());
46 }
47}
48
49#[test]
50fn test_dir_exists_after_creation() {
51 let path = "/tmp/ephemeral_dir_test";
52 let res_dir = EphemeralDir::new_forced(path);
53 assert!(res_dir.is_ok());
54 let Ok(dir) = res_dir else { unreachable!() };
55 assert!(dir.path().exists());
56 let dir_path_str = format!("{}", dir.path().display());
57 assert_eq!(dir_path_str, path);
58}
59
60#[test]
61fn test_dir_does_not_exist_after_going_out_of_scope() {
62 let path = "/tmp/ephemeral_dir_test";
63 let res_dir = EphemeralDir::new_forced(path);
64 assert!(res_dir.is_ok());
65 {
66 let Ok(dir) = res_dir else { unreachable!() };
67 assert!(dir.path().exists());
68 let dir_path_str = format!("{}", dir.path().display());
69 assert_eq!(dir_path_str, path);
70 let dir_path = Path::new(&dir_path_str);
71 assert!(dir_path.exists());
72 }
73 let path_path = Path::new(path);
74 assert!(!path_path.exists());
75}
76
77#[test]
78fn test_wrapper_functions() {
79 let path = "/tmp/ephemeral_dir_test";
81 let res_dir = ephemeral_dir(path);
82 assert!(res_dir.is_ok());
83 let Ok(dir) = res_dir else { unreachable!() };
84 assert!(dir.path().exists());
85 let dir_path_str = format!("{}", dir.path().display());
86 assert_eq!(dir_path_str, path);
87
88 let path = "/tmp/ephemeral_dir_test";
90 let res_dir = ephemeral_dir_forced(path);
91 assert!(res_dir.is_ok());
92 {
93 let Ok(dir) = res_dir else { unreachable!() };
94 assert!(dir.path().exists());
95 let dir_path_str = format!("{}", dir.path().display());
96 assert_eq!(dir_path_str, path);
97 let dir_path = Path::new(&dir_path_str);
98 assert!(dir_path.exists());
99 }
100 let path_path = Path::new(path);
101 assert!(!path_path.exists());
102}