Skip to content

Commit 2c0dcb5

Browse files
committed
Provide remove_dir_contents
This is the caller for remove_file_or_dir_all so we can get rid of the temporary `#[allow]` annocations. Signed-off-by: Ian Jackson <[email protected]>
1 parent 549d377 commit 2c0dcb5

File tree

4 files changed

+39
-3
lines changed

4 files changed

+39
-3
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
A reliable implementation of `remove_dir_all` for Windows. For Unix systems
1010
re-exports `std::fs::remove_dir_all`.
1111

12+
Also provides `remove_dir_contents` for both Windows and Unix. This
13+
removes just the contents of the directory, if it exists.
14+
1215
```rust,no_run
1316
extern crate remove_dir_all;
1417

src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
//!
33
//! This library provides a reliable implementation of `remove_dir_all` for Windows.
44
//! For Unix systems, it re-exports `std::fs::remove_dir_all`.
5-
6-
#![allow(unused_imports)] // temporary
7-
#![allow(dead_code)] // temporary
5+
//!
6+
//! It also provides `remove_dir_contents` for both Unix and Windows.
87
98
#![deny(missing_debug_implementations)]
109
#![deny(missing_docs)]
@@ -36,3 +35,6 @@ use self::unix::remove_file_or_dir_all;
3635

3736
#[cfg(not(windows))]
3837
pub use std::fs::remove_dir_all;
38+
39+
mod portable;
40+
pub use portable::*;

src/portable.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use std::fs;
2+
use std::io;
3+
use std::path::Path;
4+
5+
/// Deletes the contents of `dir_path`, but not the directory iteself.
6+
///
7+
/// If `dir_path` is a symlink to a directory, deletes the contents
8+
/// of that directory. If `dir_path` does not exist, simply returns
9+
/// (without deleting anything).
10+
pub fn remove_dir_contents(dir_path: &Path) -> Result<(), io::Error> {
11+
// On Unix, looking into the directory and removing the entries
12+
// separately is obviously right.
13+
//
14+
// On Windows, it is also right. For non-directories,
15+
// `remove_file_or_dir_all` is obviously right. For directories,
16+
// we want to treat our `dir_path` as the base dir for the complex
17+
// `remove_some` implementation.
18+
19+
let entries = match fs::read_dir(dir_path) {
20+
Err(e) if e.kind() == io::ErrorKind::NotFound => return Ok(()),
21+
r => r,
22+
}?;
23+
24+
for entry in entries {
25+
let entry_path = entry?.path();
26+
crate::remove_file_or_dir_all(&entry_path)?;
27+
}
28+
29+
Ok(())
30+
}

src/unix.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ extern crate libc;
66

77
pub(crate) fn remove_file_or_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
88
match fs::remove_file(&path) {
9+
// Unfortunately, there is no ErrorKind for EISDIR
910
Err(e) if e.raw_os_error() == Some(libc::EISDIR) => fs::remove_dir_all(&path),
1011
r => r,
1112
}

0 commit comments

Comments
 (0)