Skip to content
This repository was archived by the owner on Aug 20, 2021. It is now read-only.

Commit 1b77f7d

Browse files
authored
Merge pull request #11 from brson/next
Add lots of docs. Rust doc days!
2 parents 1093b56 + eed6168 commit 1b77f7d

File tree

1 file changed

+212
-21
lines changed

1 file changed

+212
-21
lines changed

src/lib.rs

Lines changed: 212 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,43 @@
1313
html_root_url = "https://doc.rust-lang.org/tempdir/")]
1414
#![cfg_attr(test, deny(warnings))]
1515

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+
1653
extern crate rand;
1754

1855
use std::env;
@@ -22,8 +59,50 @@ use std::fs;
2259
use std::path::{self, PathBuf, Path};
2360
use rand::{thread_rng, Rng};
2461

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
27106
pub struct TempDir {
28107
path: Option<PathBuf>,
29108
}
@@ -38,11 +117,59 @@ const NUM_RETRIES: u32 = 1 << 31;
38117
const NUM_RAND_CHARS: usize = 12;
39118

40119
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.
44154
///
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+
/// ```
46173
pub fn new_in<P: AsRef<Path>>(tmpdir: P, prefix: &str) -> io::Result<TempDir> {
47174
let storage;
48175
let mut tmpdir = tmpdir.as_ref();
@@ -76,32 +203,96 @@ impl TempDir {
76203
"too many temporary directories already exist"))
77204
}
78205

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.
82207
///
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()
86232
}
87233

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+
/// ```
91255
pub fn into_path(mut self) -> PathBuf {
92256
self.path.take().unwrap()
93257
}
94258

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`.
101260
///
102261
/// Although `TempDir` removes the directory on drop, in the destructor
103262
/// any errors are ignored. To detect errors cleaning up the temporary
104263
/// 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+
/// ```
105296
pub fn close(mut self) -> io::Result<()> {
106297
self.cleanup_dir()
107298
}

0 commit comments

Comments
 (0)