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}