1 use std::io;
2 use std::path::Path;
3
4 #[cfg(windows)]
5 use crate::fs::_remove_dir_contents;
6
7 #[cfg(not(windows))]
8 use crate::unix::_remove_dir_contents;
9
10 /// Deletes the contents of `path`, but not the directory iteself.
11 ///
12 /// If `path` is a symlink to a directory, deletes the contents
13 /// of that directory. Fails if `path` does not exist.
remove_dir_contents<P: AsRef<Path>>(path: P) -> io::Result<()>14 pub fn remove_dir_contents<P: AsRef<Path>>(path: P) -> io::Result<()> {
15 // This wrapper function exists because the core function
16 // for Windows, in crate::fs, returns a PathBuf, which our
17 // caller shouldn't see.
18 _remove_dir_contents(path)?;
19 Ok(())
20 }
21
22 /// Makes `path` an empty directory: if it does not exist, it is
23 /// created it as an empty directory (as if with
24 /// `std::fs::create_dir`); if it does exist, its contents are
25 /// deleted (as if with `remove_dir_contents`).
26 ///
27 /// It is an error if `path` exists but is not a directory (or
28 /// a symlink to one).
ensure_empty_dir<P: AsRef<Path>>(path: P) -> io::Result<()>29 pub fn ensure_empty_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
30 match std::fs::create_dir(&path) {
31 Err(e) if e.kind() == io::ErrorKind::AlreadyExists
32 => remove_dir_contents(path),
33 otherwise => otherwise,
34 }
35 }
36
37 #[cfg(test)]
38 mod test {
39 use tempfile::TempDir;
40 use crate::remove_dir_all;
41 use crate::remove_dir_contents;
42 use crate::ensure_empty_dir;
43 use std::fs::{self, File};
44 use std::path::PathBuf;
45 use std::io;
46
expect_failure<T>(k: io::ErrorKind, r: io::Result<T>) -> io::Result<()>47 fn expect_failure<T>(k: io::ErrorKind, r: io::Result<T>) -> io::Result<()> {
48 match r {
49 Err(e) if e.kind() == k => Ok(()),
50 Err(e) => Err(e),
51 Ok(_) => Err(io::Error::new(
52 io::ErrorKind::Other,
53 "unexpected success".to_string(),
54 )),
55 }
56 }
57
58 struct Prep {
59 _tmp: TempDir,
60 ours: PathBuf,
61 file: PathBuf,
62 }
63
prep() -> Result<Prep, io::Error>64 fn prep() -> Result<Prep, io::Error> {
65 let tmp = TempDir::new()?;
66 let ours = tmp.path().join("t.mkdir");
67 let file = ours.join("file");
68 fs::create_dir(&ours)?;
69 File::create(&file)?;
70 File::open(&file)?;
71 Ok(Prep { _tmp: tmp, ours, file })
72 }
73
74 #[test]
mkdir_rm() -> Result<(), io::Error>75 fn mkdir_rm() -> Result<(), io::Error> {
76 let p = prep()?;
77
78 expect_failure(io::ErrorKind::Other, remove_dir_contents(&p.file))?;
79
80 remove_dir_contents(&p.ours)?;
81 expect_failure(io::ErrorKind::NotFound, File::open(&p.file))?;
82
83 remove_dir_contents(&p.ours)?;
84 remove_dir_all(&p.ours)?;
85 expect_failure(io::ErrorKind::NotFound, remove_dir_contents(&p.ours))?;
86 Ok(())
87 }
88
89 #[test]
ensure_rm() -> Result<(), io::Error>90 fn ensure_rm() -> Result<(), io::Error> {
91 let p = prep()?;
92
93 expect_failure(io::ErrorKind::Other, ensure_empty_dir(&p.file))?;
94
95 ensure_empty_dir(&p.ours)?;
96 expect_failure(io::ErrorKind::NotFound, File::open(&p.file))?;
97 ensure_empty_dir(&p.ours)?;
98
99 remove_dir_all(&p.ours)?;
100 ensure_empty_dir(&p.ours)?;
101 File::create(&p.file)?;
102
103 Ok(())
104 }
105 }
106