drop_dir/lib.rs
1// Copyright 2020 by Matthew James Briggs
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4#[cfg(test)]
5extern crate uuid;
6
7use std::fs;
8use std::ops::Drop;
9use std::path::PathBuf;
10
11/// Represents a Directory that will be automatically deleted when it goes out of scope.
12///
13/// # Example
14///
15/// ```
16/// use std::path::PathBuf;
17/// use drop_dir::DropDir;
18/// use std::fs::File;
19///
20/// let drop_dir = DropDir::new(PathBuf::from("/tmp/some/path")).unwrap();
21/// let mut file = File::create(drop_dir.path().join("file.txt")).unwrap();
22/// // drop_dir deleted when it goes out of scope.
23/// ```
24/// ## Limitation
25///
26/// In the example above, only the last component of the `drop_dir` is removed.
27/// That is, the dir `/tmp/some/temp/path` is deleted, but `/tmp/some/temp` remains.
28/// Any other behavior would get complicated.
29///
30pub struct DropDir {
31 path_buf: PathBuf,
32}
33
34impl Drop for DropDir {
35 fn drop(&mut self) {
36 let result = fs::remove_dir_all(&self.path_buf);
37 if result.is_err() {
38 println!(
39 "Could not delete directory '{}': {}",
40 self.path_buf.to_string_lossy(),
41 result.err().unwrap()
42 );
43 }
44 }
45}
46
47impl DropDir {
48 /// # new
49 ///
50 /// Constructs a new DropDir object from a PathBuf.
51 /// Creates the directory at PathBuf if it does not exist (using `fs::create_dir_all`).
52 ///
53 /// # Example
54 /// ```
55 /// # use std::path::PathBuf;
56 /// # use drop_dir::DropDir;
57 /// # use std::fs::File;
58 /// let drop_dir = DropDir::new(PathBuf::from("/tmp/some/path")).unwrap();
59 /// ```
60 pub fn new(path_buf: PathBuf) -> Result<DropDir, std::io::Error> {
61 fs::create_dir_all(&path_buf)?;
62 Ok(DropDir { path_buf })
63 }
64
65 /// # path
66 ///
67 /// Returns a clone of the internally held PathBuf.
68 ///
69 /// # Example
70 ///
71 /// ```
72 /// # use std::path::PathBuf;
73 /// # use drop_dir::DropDir;
74 /// # use std::fs::File;
75 /// # let drop_dir = DropDir::new(PathBuf::from("/tmp/some/path")).unwrap();
76 /// let path_str = drop_dir.path().to_string_lossy();
77 /// ```
78 pub fn path(&self) -> PathBuf {
79 self.path_buf.clone()
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use std::path::Path;
86
87 use uuid::Uuid;
88
89 use super::*;
90
91 #[test]
92 fn test() {
93 let uuid = Uuid::new_v4().to_string();
94 let path_buf = std::env::temp_dir().join(uuid);
95 // Create a drop_dir within a scope
96 {
97 let _drop_dir = DropDir::new(path_buf.clone()).unwrap();
98 assert!(Path::new(&path_buf).exists())
99 }
100 assert!(!Path::new(&path_buf).exists())
101 }
102}