diff --git a/Cargo.toml b/Cargo.toml index c8f84b7..61d4b00 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "mktemp" -description = "mktemp files and directories" -homepage = "https://docs.rs/mktemp" +name = "mktemp" +description = "mktemp files and directories" +homepage = "https://docs.rs/mktemp" documentation = "https://docs.rs/mktemp" repository = "https://github.com/samgiles/rs-mktemp" version = "0.5.1" diff --git a/src/lib.rs b/src/lib.rs index b641e95..a66a05c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,11 +39,21 @@ fn create_path() -> PathBuf { create_path_in(env::temp_dir()) } +fn create_path_with_ext(extension: &str) -> PathBuf { + create_path_with_ext_in(env::temp_dir(), extension) +} + fn create_path_in(path: PathBuf) -> PathBuf { + create_path_with_ext_in(path, "") +} + +fn create_path_with_ext_in(path: PathBuf, extension: &str) -> PathBuf { let mut path = path; let dir_uuid = Uuid::new_v4(); + let ext = extension.strip_prefix('.').unwrap_or(extension); path.push(dir_uuid.simple().to_string()); + path.set_extension(ext); path } @@ -88,6 +98,31 @@ impl Temp { Ok(temp) } + /// Create a temporary file with a specified extension. `ext` can either be prefixed with '.' + /// or not. + pub fn new_file_with_extension(extension: &str) -> io::Result { + let path = create_path_with_ext(extension); + Self::create_file(&path)?; + + let temp = Temp { path }; + + Ok(temp) + } + + /// Create a temporary file with a specified extension in an existing directory. `ext` can + /// either be prefixed with '.' or not. + pub fn new_file_with_extension_in>( + directory: P, + extension: &str, + ) -> io::Result { + let path = create_path_with_ext_in(directory.as_ref().to_path_buf(), extension); + Self::create_file(&path)?; + + let temp = Temp { path }; + + Ok(temp) + } + /// Create new uninitialized temporary path, i.e. a file or directory isn't created automatically pub fn new_path() -> Self { let path = create_path(); @@ -103,6 +138,22 @@ impl Temp { Temp { path } } + /// Create new uninitialized temporary path with extension, i.e. a file or directory isn't + /// created automatically + pub fn new_path_with_extension(extension: &str) -> Self { + let path = create_path_with_ext(extension); + + Temp { path } + } + + /// Create a new uninitialized temporary path with extension in an existing directory i.e. a file + /// or directory isn't created automatically + pub fn new_path_with_extension_in>(directory: P, extension: &str) -> Self { + let path = create_path_with_ext_in(directory.as_ref().to_path_buf(), extension); + + Temp { path } + } + /// Return this temporary file or directory as a PathBuf. /// /// # Examples @@ -197,9 +248,9 @@ impl Drop for Temp { #[cfg(test)] mod tests { use super::*; - use std::fs::File; #[cfg(unix)] use std::os::unix::fs::MetadataExt; + use std::{ffi::OsStr, fs::File}; #[test] fn it_should_create_file_in_dir() { @@ -216,6 +267,36 @@ mod tests { } } + #[test] + fn it_should_create_file_with_ext() { + let temp_file = Temp::new_file_with_extension("json").unwrap(); + assert_eq!(&temp_file.extension(), &Some(OsStr::new("json"))); + assert!(fs::metadata(temp_file).unwrap().is_file()); + } + + #[test] + fn it_should_create_file_with_ext_stripping_dot() { + let temp_file = Temp::new_file_with_extension(".json").unwrap(); + assert_eq!(&temp_file.extension(), &Some(OsStr::new("json"))); + assert!(fs::metadata(temp_file).unwrap().is_file()); + } + + #[test] + fn it_should_create_file_with_ext_in() { + let in_dir; + { + let temp_dir = Temp::new_dir().unwrap(); + + in_dir = temp_dir.path.clone(); + + { + let temp_file = Temp::new_file_with_extension_in(in_dir, "json").unwrap(); + assert_eq!(&temp_file.extension(), &Some(OsStr::new("json"))); + assert!(fs::metadata(temp_file).unwrap().is_file()); + } + } + } + #[test] fn it_should_drop_file_out_of_scope() { let path;