13
13
html_root_url = "https://doc.rust-lang.org/tempdir/" ) ]
14
14
#![ cfg_attr( test, deny( warnings) ) ]
15
15
16
+ //! Temporary directories of files.
17
+ //!
18
+ //! The [`TempDir`] type creates a directory on the file system that
19
+ //! is deleted once it goes out of scope. At construction, the
20
+ //! `TempDir` creates a new directory with a randomly generated name
21
+ //! and a prefix of your choosing.
22
+ //!
23
+ //! [`TempDir`]: struct.TempDir.html
24
+ //! [`std::env::temp_dir()`]: https://doc.rust-lang.org/std/env/fn.temp_dir.html
25
+ //!
26
+ //! # Examples
27
+ //!
28
+ //! ```
29
+ //! extern crate tempdir;
30
+ //!
31
+ //! use std::fs::File;
32
+ //! use std::io::Write;
33
+ //! use tempdir::TempDir;
34
+ //!
35
+ //! fn main() {
36
+ //! // Create a directory inside of `std::env::temp_dir()`, named with
37
+ //! // the prefix "example".
38
+ //! let tmp_dir = TempDir::new("example").expect("create temp dir");
39
+ //! let file_path = tmp_dir.path().join("my-temporary-note.txt");
40
+ //! let mut tmp_file = File::create(file_path).expect("create temp file");
41
+ //! writeln!(tmp_file, "Brian was here. Briefly.").expect("write temp file");
42
+ //!
43
+ //! // By closing the `TempDir` explicitly, we can check that it has
44
+ //! // been deleted successfully. If we don't close it explicitly,
45
+ //! // the directory will still be deleted when `tmp_dir` goes out
46
+ //! // of scope, but we won't know whether deleting the directory
47
+ //! // succeeded.
48
+ //! drop(tmp_file);
49
+ //! tmp_dir.close().expect("delete temp dir");
50
+ //! }
51
+ //! ```
52
+
16
53
extern crate rand;
17
54
18
55
use std:: env;
@@ -22,8 +59,50 @@ use std::fs;
22
59
use std:: path:: { self , PathBuf , Path } ;
23
60
use rand:: { thread_rng, Rng } ;
24
61
25
- /// A wrapper for a path to temporary directory implementing automatic
26
- /// scope-based deletion.
62
+ /// A directory in the filesystem that is automatically deleted when
63
+ /// it goes out of scope.
64
+ ///
65
+ /// The [`TempDir`] type creates a directory on the file system that
66
+ /// is deleted once it goes out of scope. At construction, the
67
+ /// `TempDir` creates a new directory with a randomly generated name,
68
+ /// and with a prefix of your choosing.
69
+ ///
70
+ /// The default constructor, [`TempDir::new`], creates directories in
71
+ /// the location returned by [`std::env::temp_dir()`], but `TempDir`
72
+ /// can be configured to manage a temporary directory in any location
73
+ /// by constructing with [`TempDir::new_in`].
74
+ ///
75
+ /// After creating a `TempDir`, work with the file system by doing
76
+ /// standard [`std::fs`] file system operations on its [`Path`],
77
+ /// which can be retrieved with [`TempDir::path`]. Once the `TempDir`
78
+ /// value is dropped, the directory at the path will be deleted, along
79
+ /// with any files and directories it contains. It is your responsibility
80
+ /// to ensure that no further file system operations are attempted
81
+ /// inside the temporary directory once it has been deleted.
82
+ ///
83
+ /// Various platform-specific conditions may cause `TempDir` to fail
84
+ /// to delete the underlying directory. It's important to ensure that
85
+ /// handles (like [`File`] and [`ReadDir`]) to files inside the
86
+ /// directory are dropped before the `TempDir` goes out of scope. The
87
+ /// `TempDir` destructor will silently ignore any errors in deleting
88
+ /// the directory; to instead handle errors call [`TempDir::close`].
89
+ ///
90
+ /// Note that if the program exits before the `TempDir` destructor is
91
+ /// run, such as via [`std::process::exit`], by segfaulting, or by
92
+ /// receiving a signal like `SIGINT`, then the temporary directory
93
+ /// will not be deleted.
94
+ ///
95
+ /// [`File`]: http://doc.rust-lang.org/std/fs/struct.File.html
96
+ /// [`Path`]: http://doc.rust-lang.org/std/path/struct.Path.html
97
+ /// [`ReadDir`]: http://doc.rust-lang.org/std/fs/struct.ReadDir.html
98
+ /// [`TempDir::close`]: struct.TempDir.html#method.close
99
+ /// [`TempDir::new`]: struct.TempDir.html#method.new
100
+ /// [`TempDir::new_in`]: struct.TempDir.html#method.new_in
101
+ /// [`TempDir::path`]: struct.TempDir.html#method.path
102
+ /// [`TempDir`]: struct.TempDir.html
103
+ /// [`std::env::temp_dir()`]: https://doc.rust-lang.org/std/env/fn.temp_dir.html
104
+ /// [`std::fs`]: http://doc.rust-lang.org/std/fs/index.html
105
+ /// [`std::process::exit`]: http://doc.rust-lang.org/std/process/fn.exit.html
27
106
pub struct TempDir {
28
107
path : Option < PathBuf > ,
29
108
}
@@ -38,11 +117,59 @@ const NUM_RETRIES: u32 = 1 << 31;
38
117
const NUM_RAND_CHARS : usize = 12 ;
39
118
40
119
impl TempDir {
41
- /// Attempts to make a temporary directory inside of `tmpdir` whose name
42
- /// will have the prefix `prefix`. The directory will be automatically
43
- /// deleted once the returned wrapper is destroyed.
120
+ /// Attempts to make a temporary directory inside of `env::temp_dir()` whose
121
+ /// name will have the prefix, `prefix`. The directory and
122
+ /// everything inside it will be automatically deleted once the
123
+ /// returned `TempDir` is destroyed.
124
+ ///
125
+ /// # Errors
126
+ ///
127
+ /// If the directory can not be created, `Err` is returned.
128
+ ///
129
+ /// # Examples
130
+ ///
131
+ /// ```
132
+ /// use std::fs::File;
133
+ /// use std::io::Write;
134
+ /// use tempdir::TempDir;
135
+ ///
136
+ /// // Create a directory inside of `std::env::temp_dir()`, named with
137
+ /// // the prefix, "example".
138
+ /// let tmp_dir = TempDir::new("example").expect("create temp dir");
139
+ /// let file_path = tmp_dir.path().join("my-temporary-note.txt");
140
+ /// let mut tmp_file = File::create(file_path).expect("create temp file");
141
+ /// writeln!(tmp_file, "Brian was here. Briefly.").expect("write temp file");
142
+ ///
143
+ /// // `tmp_dir` goes out of scope, the directory as well as
144
+ /// // `tmp_file` will be deleted here.
145
+ /// ```
146
+ pub fn new ( prefix : & str ) -> io:: Result < TempDir > {
147
+ TempDir :: new_in ( & env:: temp_dir ( ) , prefix)
148
+ }
149
+
150
+ /// Attempts to make a temporary directory inside of `tmpdir`
151
+ /// whose name will have the prefix `prefix`. The directory and
152
+ /// everything inside it will be automatically deleted once the
153
+ /// returned `TempDir` is destroyed.
44
154
///
45
- /// If no directory can be created, `Err` is returned.
155
+ /// # Errors
156
+ ///
157
+ /// If the directory can not be created, `Err` is returned.
158
+ ///
159
+ /// # Examples
160
+ ///
161
+ /// ```
162
+ /// use std::fs::{self, File};
163
+ /// use std::io::Write;
164
+ /// use tempdir::TempDir;
165
+ ///
166
+ /// // Create a directory inside of the current directory, named with
167
+ /// // the prefix, "example".
168
+ /// let tmp_dir = TempDir::new_in(".", "example").expect("create temp dir");
169
+ /// let file_path = tmp_dir.path().join("my-temporary-note.txt");
170
+ /// let mut tmp_file = File::create(file_path).expect("create temp file");
171
+ /// writeln!(tmp_file, "Brian was here. Briefly.").expect("write temp file");
172
+ /// ```
46
173
pub fn new_in < P : AsRef < Path > > ( tmpdir : P , prefix : & str ) -> io:: Result < TempDir > {
47
174
let storage;
48
175
let mut tmpdir = tmpdir. as_ref ( ) ;
@@ -76,32 +203,96 @@ impl TempDir {
76
203
"too many temporary directories already exist" ) )
77
204
}
78
205
79
- /// Attempts to make a temporary directory inside of `env::temp_dir()` whose
80
- /// name will have the prefix `prefix`. The directory will be automatically
81
- /// deleted once the returned wrapper is destroyed.
206
+ /// Accesses the [`Path`] to the temporary directory.
82
207
///
83
- /// If no directory can be created, `Err` is returned.
84
- pub fn new ( prefix : & str ) -> io:: Result < TempDir > {
85
- TempDir :: new_in ( & env:: temp_dir ( ) , prefix)
208
+ /// [`Path`]: http://doc.rust-lang.org/std/path/struct.Path.html
209
+ ///
210
+ /// # Examples
211
+ ///
212
+ /// ```
213
+ /// use tempdir::TempDir;
214
+ ///
215
+ /// let tmp_path;
216
+ ///
217
+ /// {
218
+ /// let tmp_dir = TempDir::new("example").expect("create temp dir");
219
+ /// tmp_path = tmp_dir.path().to_owned();
220
+ ///
221
+ /// // Check that the temp directory actually exists.
222
+ /// assert!(tmp_path.exists());
223
+ ///
224
+ /// // End of `tmp_dir` scope, directory will be deleted
225
+ /// }
226
+ ///
227
+ /// // Temp directory should be deleted by now
228
+ /// assert_eq!(tmp_path.exists(), false);
229
+ /// ```
230
+ pub fn path ( & self ) -> & path:: Path {
231
+ self . path . as_ref ( ) . unwrap ( )
86
232
}
87
233
88
- /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper.
89
- /// This discards the wrapper so that the automatic deletion of the
90
- /// temporary directory is prevented.
234
+ /// Unwraps the [`Path`] contained in the `TempDir` and
235
+ /// returns it. This destroys the `TempDir` without deleting the
236
+ /// directory represented by the returned `Path`.
237
+ ///
238
+ /// [`Path`]: http://doc.rust-lang.org/std/path/struct.Path.html
239
+ ///
240
+ /// # Examples
241
+ ///
242
+ /// ```
243
+ /// use std::fs;
244
+ /// use tempdir::TempDir;
245
+ ///
246
+ /// let tmp_dir = TempDir::new("example").expect("create temp dir");
247
+ ///
248
+ /// // Convert `tmp_dir` into a `Path`, destroying the `TempDir`
249
+ /// // without deleting the directory.
250
+ /// let tmp_path = tmp_dir.into_path();
251
+ ///
252
+ /// // Delete the temporary directory ourselves.
253
+ /// fs::remove_dir_all(tmp_path).expect("remove temp dir");
254
+ /// ```
91
255
pub fn into_path ( mut self ) -> PathBuf {
92
256
self . path . take ( ) . unwrap ( )
93
257
}
94
258
95
- /// Access the wrapped `std::path::Path` to the temporary directory.
96
- pub fn path ( & self ) -> & path:: Path {
97
- self . path . as_ref ( ) . unwrap ( )
98
- }
99
-
100
- /// Close and remove the temporary directory
259
+ /// Closes and removes the temporary directory, returing a `Result`.
101
260
///
102
261
/// Although `TempDir` removes the directory on drop, in the destructor
103
262
/// any errors are ignored. To detect errors cleaning up the temporary
104
263
/// directory, call `close` instead.
264
+ ///
265
+ /// # Errors
266
+ ///
267
+ /// This function may return a variety of [`std::io::Error`]s that result from deleting
268
+ /// the files and directories contained with the temporary directory,
269
+ /// as well as from deleting the temporary directory itself. These errors
270
+ /// may be platform specific.
271
+ ///
272
+ /// [`std::io::Error`]: http://doc.rust-lang.org/std/io/struct.Error.html
273
+ ///
274
+ /// # Examples
275
+ ///
276
+ /// ```
277
+ /// use std::fs::File;
278
+ /// use std::io::Write;
279
+ /// use tempdir::TempDir;
280
+ ///
281
+ /// // Create a directory inside of `std::env::temp_dir()`, named with
282
+ /// // the prefix, "example".
283
+ /// let tmp_dir = TempDir::new("example").expect("create temp dir");
284
+ /// let file_path = tmp_dir.path().join("my-temporary-note.txt");
285
+ /// let mut tmp_file = File::create(file_path).expect("create temp file");
286
+ /// writeln!(tmp_file, "Brian was here. Briefly.").expect("write temp file");
287
+ ///
288
+ /// // By closing the `TempDir` explicitly we can check that it has
289
+ /// // been deleted successfully. If we don't close it explicitly,
290
+ /// // the directory will still be deleted when `tmp_dir` goes out
291
+ /// // of scope, but we won't know whether deleting the directory
292
+ /// // succeeded.
293
+ /// drop(tmp_file);
294
+ /// tmp_dir.close().expect("delete temp dir");
295
+ /// ```
105
296
pub fn close ( mut self ) -> io:: Result < ( ) > {
106
297
self . cleanup_dir ( )
107
298
}
0 commit comments