diff options
author | Jeff Vander Stoep <jeffv@google.com> | 2023-02-06 09:09:48 +0100 |
---|---|---|
committer | Jeff Vander Stoep <jeffv@google.com> | 2023-02-06 09:09:48 +0100 |
commit | 4578b5b3b34d2dc74034747ceda1ebffa9c9acc5 (patch) | |
tree | 632a499f62c12dc7f097c0214344371ef9d8384c | |
parent | 05984ae3288310c34218fbeaf6e114f3881cd406 (diff) | |
download | tempfile-4578b5b3b34d2dc74034747ceda1ebffa9c9acc5.tar.gz |
Upgrade tempfile to 3.3.0
This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update rust/crates/tempfile
For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
Test: TreeHugger
Change-Id: Ida34064265fa66471afd5f1c831a627779165d2e
-rw-r--r-- | .cargo_vcs_info.json | 6 | ||||
-rw-r--r-- | .github/workflows/ci.yml | 52 | ||||
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Android.bp | 4 | ||||
-rw-r--r-- | Cargo.toml | 59 | ||||
-rw-r--r-- | Cargo.toml.orig | 42 | ||||
-rw-r--r-- | METADATA | 15 | ||||
-rw-r--r-- | NEWS | 15 | ||||
-rw-r--r-- | src/dir.rs | 31 | ||||
-rw-r--r-- | src/file/imp/mod.rs | 2 | ||||
-rw-r--r-- | src/file/imp/unix.rs | 2 | ||||
-rw-r--r-- | src/file/mod.rs | 30 | ||||
-rw-r--r-- | src/lib.rs | 45 | ||||
-rw-r--r-- | src/spooled.rs | 42 | ||||
-rw-r--r-- | src/util.rs | 29 | ||||
-rw-r--r-- | tests/namedtempfile.rs | 49 |
16 files changed, 317 insertions, 108 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json new file mode 100644 index 0000000..cabd9cd --- /dev/null +++ b/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "1a40687e06eb656044e3d2dffa1379f04b3ef3fd" + }, + "path_in_vcs": "" +}
\ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..0d7c068 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,52 @@ +on: [push] +name: CI +jobs: + build_and_test: + name: OS Test + strategy: + matrix: + rust-version: + - nightly + - "1.40" + os: + - ubuntu-latest + - windows-latest + - macos-latest + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust-version }} + default: true + - name: Build + uses: actions-rs/cargo@v1 + with: + command: build + - name: Test + uses: actions-rs/cargo@v1 + with: + command: test + wasm: + name: WASM Test Build + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + default: true + - name: Install Cargo WASI + uses: actions-rs/cargo@v1 + with: + command: install + args: cargo-wasi + - name: Build + uses: actions-rs/cargo@v1 + with: + command: wasi + args: build --features nightly diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a9d37c5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock @@ -42,13 +42,13 @@ rust_library { host_supported: true, crate_name: "tempfile", cargo_env_compat: true, - cargo_pkg_version: "3.2.0", + cargo_pkg_version: "3.3.0", srcs: ["src/lib.rs"], edition: "2018", rustlibs: [ "libcfg_if", + "libfastrand", "liblibc", - "librand", "libremove_dir_all", ], apex_available: [ @@ -1,42 +1,43 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + [package] -name = "tempfile" -version = "3.2.0" -authors = [ - "Steven Allen <steven@stebalien.com>", - "The Rust Project Developers", - "Ashley Mannix <ashleymannix@live.com.au>", - "Jason White <jasonaw0@gmail.com>", -] -documentation = "https://docs.rs/tempfile" edition = "2018" +name = "tempfile" +version = "3.3.0" +authors = ["Steven Allen <steven@stebalien.com>", "The Rust Project Developers", "Ashley Mannix <ashleymannix@live.com.au>", "Jason White <jasonaw0@gmail.com>"] exclude = ["/.travis.yml", "/appveyor.yml"] +description = "A library for managing temporary files and directories." homepage = "http://stebalien.com/projects/tempfile-rs" +documentation = "https://docs.rs/tempfile" keywords = ["tempfile", "tmpfile", "filesystem"] license = "MIT OR Apache-2.0" repository = "https://github.com/Stebalien/tempfile" -description = "A library for managing temporary files and directories." - -[dependencies] -cfg-if = "1" -rand = { version = "0.8", features = ["small_rng", "getrandom"], default_features = false } -remove_dir_all = "0.5" +[dependencies.cfg-if] +version = "1" -[target.'cfg(any(unix, target_os = "wasi"))'.dependencies] -libc = "0.2.27" +[dependencies.fastrand] +version = "1.6.0" -[target.'cfg(windows)'.dependencies.winapi] +[dependencies.remove_dir_all] +version = "0.5" +[dev-dependencies.doc-comment] version = "0.3" -features = [ - "fileapi", - "handleapi", - "winbase", -] - -[target.'cfg(target_os = "redox")'.dependencies] -redox_syscall = "0.2" - -[dev-dependencies] -doc-comment = "0.3" [features] nightly = [] +[target."cfg(any(unix, target_os = \"wasi\"))".dependencies.libc] +version = "0.2.27" +[target."cfg(target_os = \"redox\")".dependencies.redox_syscall] +version = "0.2.9" +[target."cfg(windows)".dependencies.winapi] +version = "0.3" +features = ["fileapi", "handleapi", "winbase"] diff --git a/Cargo.toml.orig b/Cargo.toml.orig new file mode 100644 index 0000000..c5729c8 --- /dev/null +++ b/Cargo.toml.orig @@ -0,0 +1,42 @@ +[package] +name = "tempfile" +version = "3.3.0" +authors = [ + "Steven Allen <steven@stebalien.com>", + "The Rust Project Developers", + "Ashley Mannix <ashleymannix@live.com.au>", + "Jason White <jasonaw0@gmail.com>", +] +documentation = "https://docs.rs/tempfile" +edition = "2018" +exclude = ["/.travis.yml", "/appveyor.yml"] +homepage = "http://stebalien.com/projects/tempfile-rs" +keywords = ["tempfile", "tmpfile", "filesystem"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/Stebalien/tempfile" +description = "A library for managing temporary files and directories." + +[dependencies] +cfg-if = "1" +fastrand = "1.6.0" +remove_dir_all = "0.5" + +[target.'cfg(any(unix, target_os = "wasi"))'.dependencies] +libc = "0.2.27" + +[target.'cfg(windows)'.dependencies.winapi] +version = "0.3" +features = [ + "fileapi", + "handleapi", + "winbase", +] + +[target.'cfg(target_os = "redox")'.dependencies] +redox_syscall = "0.2.9" + +[dev-dependencies] +doc-comment = "0.3" + +[features] +nightly = [] @@ -1,3 +1,7 @@ +# This project was upgraded with external_updater. +# Usage: tools/external_updater/updater.sh update rust/crates/tempfile +# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md + name: "tempfile" description: "A library for managing temporary files and directories." third_party { @@ -7,14 +11,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/tempfile/tempfile-3.2.0.crate" + value: "https://static.crates.io/crates/tempfile/tempfile-3.3.0.crate" } - version: "3.2.0" - # Dual-licensed, using the least restrictive per go/thirdpartylicenses#same. + version: "3.3.0" license_type: NOTICE last_upgrade_date { - year: 2021 - month: 10 - day: 25 + year: 2023 + month: 2 + day: 6 } } @@ -1,3 +1,18 @@ +3.3.0 +===== + +Features: + +* Replace rand with fastrand for a significantly smaller dependency tree. Cryptographic randomness + isn't necessary for temporary file names, and isn't all that helpful either. +* Add limited WASI support. +* Add a function to extract the inner data from a `SpooledTempFile`. + +Bug Fixes: + +* Make it possible to persist unnamed temporary files on linux by removing the `O_EXCL` flag. +* Fix redox minimum crate version. + 3.2.0 ===== @@ -9,6 +9,7 @@ // except according to those terms. use remove_dir_all::remove_dir_all; +use std::mem; use std::path::{self, Path, PathBuf}; use std::{fmt, fs, io}; @@ -192,7 +193,7 @@ pub fn tempdir_in<P: AsRef<Path>>(dir: P) -> io::Result<TempDir> { /// [`std::fs`]: http://doc.rust-lang.org/std/fs/index.html /// [`std::process::exit()`]: http://doc.rust-lang.org/std/process/fn.exit.html pub struct TempDir { - path: Option<PathBuf>, + path: Box<Path>, } impl TempDir { @@ -292,7 +293,7 @@ impl TempDir { /// # } /// ``` pub fn path(&self) -> &path::Path { - self.path.as_ref().unwrap() + self.path.as_ref() } /// Persist the temporary directory to disk, returning the [`PathBuf`] where it is located. @@ -322,8 +323,13 @@ impl TempDir { /// # Ok(()) /// # } /// ``` - pub fn into_path(mut self) -> PathBuf { - self.path.take().unwrap() + pub fn into_path(self) -> PathBuf { + // Prevent the Drop impl from being called. + let mut this = mem::ManuallyDrop::new(self); + + // replace this.path with an empty Box, since an empty Box does not + // allocate any heap memory. + mem::replace(&mut this.path, PathBuf::new().into_boxed_path()).into() } /// Closes and removes the temporary directory, returning a `Result`. @@ -369,8 +375,12 @@ impl TempDir { pub fn close(mut self) -> io::Result<()> { let result = remove_dir_all(self.path()).with_err_path(|| self.path()); - // Prevent the Drop impl from removing the dir a second time. - self.path = None; + // Set self.path to empty Box to release the memory, since an empty + // Box does not allocate any heap memory. + self.path = PathBuf::new().into_boxed_path(); + + // Prevent the Drop impl from being called. + mem::forget(self); result } @@ -392,15 +402,14 @@ impl fmt::Debug for TempDir { impl Drop for TempDir { fn drop(&mut self) { - // Path is `None` if `close()` or `into_path()` has been called. - if let Some(ref p) = self.path { - let _ = remove_dir_all(p); - } + let _ = remove_dir_all(self.path()); } } pub(crate) fn create(path: PathBuf) -> io::Result<TempDir> { fs::create_dir(&path) .with_err_path(|| &path) - .map(|_| TempDir { path: Some(path) }) + .map(|_| TempDir { + path: path.into_boxed_path(), + }) } diff --git a/src/file/imp/mod.rs b/src/file/imp/mod.rs index ceb630e..fbb2bbf 100644 --- a/src/file/imp/mod.rs +++ b/src/file/imp/mod.rs @@ -1,4 +1,4 @@ -cfg_if! { +cfg_if::cfg_if! { if #[cfg(any(unix, target_os = "redox", target_os = "wasi"))] { mod unix; pub use self::unix::*; diff --git a/src/file/imp/unix.rs b/src/file/imp/unix.rs index 89249fd..480743c 100644 --- a/src/file/imp/unix.rs +++ b/src/file/imp/unix.rs @@ -2,7 +2,7 @@ use std::env; use std::ffi::{CString, OsStr}; use std::fs::{self, File, OpenOptions}; use std::io; -cfg_if! { +cfg_if::cfg_if! { if #[cfg(not(target_os = "wasi"))] { use std::os::unix::ffi::OsStrExt; use std::os::unix::fs::{MetadataExt, OpenOptionsExt}; diff --git a/src/file/mod.rs b/src/file/mod.rs index 31fdd4b..b859ced 100644 --- a/src/file/mod.rs +++ b/src/file/mod.rs @@ -138,7 +138,7 @@ impl error::Error for PathPersistError { /// /// When dropped, the temporary file is deleted. pub struct TempPath { - path: PathBuf, + path: Box<Path>, } impl TempPath { @@ -176,8 +176,8 @@ impl TempPath { /// # } /// ``` pub fn close(mut self) -> io::Result<()> { - let result = fs::remove_file(&self.path).with_err_path(|| &self.path); - self.path = PathBuf::new(); + let result = fs::remove_file(&self.path).with_err_path(|| &*self.path); + self.path = PathBuf::new().into_boxed_path(); mem::forget(self); result } @@ -231,7 +231,7 @@ impl TempPath { // Don't drop `self`. We don't want to try deleting the old // temporary file path. (It'll fail, but the failure is never // seen.) - self.path = PathBuf::new(); + self.path = PathBuf::new().into_boxed_path(); mem::forget(self); Ok(()) } @@ -293,7 +293,7 @@ impl TempPath { // Don't drop `self`. We don't want to try deleting the old // temporary file path. (It'll fail, but the failure is never // seen.) - self.path = PathBuf::new(); + self.path = PathBuf::new().into_boxed_path(); mem::forget(self); Ok(()) } @@ -341,9 +341,9 @@ impl TempPath { // Don't drop `self`. We don't want to try deleting the old // temporary file path. (It'll fail, but the failure is never // seen.) - let path = mem::replace(&mut self.path, PathBuf::new()); + let path = mem::replace(&mut self.path, PathBuf::new().into_boxed_path()); mem::forget(self); - Ok(path) + Ok(path.into()) } Err(e) => Err(PathPersistError { error: e, @@ -351,6 +351,18 @@ impl TempPath { }), } } + + /// Create a new TempPath from an existing path. This can be done even if no + /// file exists at the given path. + /// + /// This is mostly useful for interacting with libraries and external + /// components that provide files to be consumed or expect a path with no + /// existing file to be given. + pub fn from_path(path: impl Into<PathBuf>) -> Self { + Self { + path: path.into().into_boxed_path(), + } + } } impl fmt::Debug for TempPath { @@ -953,7 +965,9 @@ pub(crate) fn create_named( imp::create_named(&path, open_options) .with_err_path(|| path.clone()) .map(|file| NamedTempFile { - path: TempPath { path }, + path: TempPath { + path: path.into_boxed_path(), + }, file, }) } @@ -27,6 +27,42 @@ //! rely on file paths for _some_ operations. See the security documentation on //! the `NamedTempFile` type for more information. //! +//! ## Early drop pitfall +//! +//! Because `TempDir` and `NamedTempFile` rely on their destructors for cleanup, this can lead +//! to an unexpected early removal of the directory/file, usually when working with APIs which are +//! generic over `AsRef<Path>`. Consider the following example: +//! +//! ```no_run +//! # use tempfile::tempdir; +//! # use std::io; +//! # use std::process::Command; +//! # fn main() { +//! # if let Err(_) = run() { +//! # ::std::process::exit(1); +//! # } +//! # } +//! # fn run() -> Result<(), io::Error> { +//! // Create a directory inside of `std::env::temp_dir()`. +//! let temp_dir = tempdir()?; +//! +//! // Spawn the `touch` command inside the temporary directory and collect the exit status +//! // Note that `temp_dir` is **not** moved into `current_dir`, but passed as a reference +//! let exit_status = Command::new("touch").arg("tmp").current_dir(&temp_dir).status()?; +//! assert!(exit_status.success()); +//! +//! # Ok(()) +//! # } +//! ``` +//! +//! This works because a reference to `temp_dir` is passed to `current_dir`, resulting in the +//! destructor of `temp_dir` being run after the `Command` has finished execution. Moving the +//! `TempDir` into the `current_dir` call would result in the `TempDir` being converted into +//! an internal representation, with the original value being dropped and the directory thus +//! being deleted, before the command can be executed. +//! +//! The `touch` command would fail with an `No such file or directory` error. +//! //! ## Examples //! //! Create a temporary file and write some data into it: @@ -127,15 +163,8 @@ #![allow(clippy::redundant_field_names)] #![cfg_attr(feature = "nightly", feature(wasi_ext))] -#[macro_use] -extern crate cfg_if; - -#[cfg(doctest)] -#[macro_use] -extern crate doc_comment; - #[cfg(doctest)] -doctest!("../README.md"); +doc_comment::doctest!("../README.md"); const NUM_RETRIES: u32 = 1 << 31; const NUM_RAND_CHARS: usize = 6; diff --git a/src/spooled.rs b/src/spooled.rs index e6f750e..ed6c16f 100644 --- a/src/spooled.rs +++ b/src/spooled.rs @@ -2,8 +2,9 @@ use crate::file::tempfile; use std::fs::File; use std::io::{self, Cursor, Read, Seek, SeekFrom, Write}; +/// A wrapper for the two states of a `SpooledTempFile`. #[derive(Debug)] -enum SpooledInner { +pub enum SpooledData { InMemory(Cursor<Vec<u8>>), OnDisk(File), } @@ -15,7 +16,7 @@ enum SpooledInner { #[derive(Debug)] pub struct SpooledTempFile { max_size: usize, - inner: SpooledInner, + inner: SpooledData, } /// Create a new spooled temporary file. @@ -66,15 +67,15 @@ impl SpooledTempFile { pub fn new(max_size: usize) -> SpooledTempFile { SpooledTempFile { max_size: max_size, - inner: SpooledInner::InMemory(Cursor::new(Vec::new())), + inner: SpooledData::InMemory(Cursor::new(Vec::new())), } } /// Returns true if the file has been rolled over to disk. pub fn is_rolled(&self) -> bool { match self.inner { - SpooledInner::InMemory(_) => false, - SpooledInner::OnDisk(_) => true, + SpooledData::InMemory(_) => false, + SpooledData::OnDisk(_) => true, } } @@ -83,11 +84,11 @@ impl SpooledTempFile { pub fn roll(&mut self) -> io::Result<()> { if !self.is_rolled() { let mut file = tempfile()?; - if let SpooledInner::InMemory(ref mut cursor) = self.inner { + if let SpooledData::InMemory(ref mut cursor) = self.inner { file.write_all(cursor.get_ref())?; file.seek(SeekFrom::Start(cursor.position()))?; } - self.inner = SpooledInner::OnDisk(file); + self.inner = SpooledData::OnDisk(file); } Ok(()) } @@ -97,20 +98,25 @@ impl SpooledTempFile { self.roll()?; // does nothing if already rolled over } match self.inner { - SpooledInner::InMemory(ref mut cursor) => { + SpooledData::InMemory(ref mut cursor) => { cursor.get_mut().resize(size as usize, 0); Ok(()) } - SpooledInner::OnDisk(ref mut file) => file.set_len(size), + SpooledData::OnDisk(ref mut file) => file.set_len(size), } } + + /// Consumes and returns the inner `SpooledData` type. + pub fn into_inner(self) -> SpooledData { + self.inner + } } impl Read for SpooledTempFile { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { match self.inner { - SpooledInner::InMemory(ref mut cursor) => cursor.read(buf), - SpooledInner::OnDisk(ref mut file) => file.read(buf), + SpooledData::InMemory(ref mut cursor) => cursor.read(buf), + SpooledData::OnDisk(ref mut file) => file.read(buf), } } } @@ -119,7 +125,7 @@ impl Write for SpooledTempFile { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { // roll over to file if necessary let mut rolling = false; - if let SpooledInner::InMemory(ref mut cursor) = self.inner { + if let SpooledData::InMemory(ref mut cursor) = self.inner { rolling = cursor.position() as usize + buf.len() > self.max_size; } if rolling { @@ -128,16 +134,16 @@ impl Write for SpooledTempFile { // write the bytes match self.inner { - SpooledInner::InMemory(ref mut cursor) => cursor.write(buf), - SpooledInner::OnDisk(ref mut file) => file.write(buf), + SpooledData::InMemory(ref mut cursor) => cursor.write(buf), + SpooledData::OnDisk(ref mut file) => file.write(buf), } } #[inline] fn flush(&mut self) -> io::Result<()> { match self.inner { - SpooledInner::InMemory(ref mut cursor) => cursor.flush(), - SpooledInner::OnDisk(ref mut file) => file.flush(), + SpooledData::InMemory(ref mut cursor) => cursor.flush(), + SpooledData::OnDisk(ref mut file) => file.flush(), } } } @@ -145,8 +151,8 @@ impl Write for SpooledTempFile { impl Seek for SpooledTempFile { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { match self.inner { - SpooledInner::InMemory(ref mut cursor) => cursor.seek(pos), - SpooledInner::OnDisk(ref mut file) => file.seek(pos), + SpooledData::InMemory(ref mut cursor) => cursor.seek(pos), + SpooledData::OnDisk(ref mut file) => file.seek(pos), } } } diff --git a/src/util.rs b/src/util.rs index 01beeed..8c91b9c 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,32 +1,17 @@ -use rand::{self, Rng, SeedableRng}; -use rand::{distributions::Alphanumeric, rngs::SmallRng}; +use fastrand; use std::ffi::{OsStr, OsString}; -use std::thread_local; -use std::{ - cell::UnsafeCell, - path::{Path, PathBuf}, -}; -use std::{io, str}; +use std::path::{Path, PathBuf}; +use std::{io, iter::repeat_with}; use crate::error::IoResultExt; -thread_local! { - static THREAD_RNG: UnsafeCell<SmallRng> = UnsafeCell::new(SmallRng::from_entropy()); -} - fn tmpname(prefix: &OsStr, suffix: &OsStr, rand_len: usize) -> OsString { let mut buf = OsString::with_capacity(prefix.len() + suffix.len() + rand_len); buf.push(prefix); - - // Push each character in one-by-one. Unfortunately, this is the only - // safe(ish) simple way to do this without allocating a temporary - // String/Vec. - THREAD_RNG.with(|rng| unsafe { - (&mut *rng.get()) - .sample_iter(&Alphanumeric) - .take(rand_len) - .for_each(|b| buf.push(str::from_utf8_unchecked(&[b as u8]))) - }); + let mut char_buf = [0u8; 4]; + for c in repeat_with(fastrand::alphanumeric).take(rand_len) { + buf.push(c.encode_utf8(&mut char_buf)); + } buf.push(suffix); buf } diff --git a/tests/namedtempfile.rs b/tests/namedtempfile.rs index a489d56..d2c7da2 100644 --- a/tests/namedtempfile.rs +++ b/tests/namedtempfile.rs @@ -1,10 +1,11 @@ #![deny(rust_2018_idioms)] use std::env; +use std::ffi::{OsStr, OsString}; use std::fs::File; use std::io::{Read, Seek, SeekFrom, Write}; -use std::path::Path; -use tempfile::{Builder, NamedTempFile}; +use std::path::{Path, PathBuf}; +use tempfile::{tempdir, Builder, NamedTempFile, TempPath}; fn exists<P: AsRef<Path>>(path: P) -> bool { std::fs::metadata(path.as_ref()).is_ok() @@ -217,6 +218,50 @@ fn test_temppath_persist_noclobber() { } #[test] +fn temp_path_from_existing() { + let tmp_dir = tempdir().unwrap(); + let tmp_file_path_1 = tmp_dir.path().join("testfile1"); + let tmp_file_path_2 = tmp_dir.path().join("testfile2"); + + File::create(&tmp_file_path_1).unwrap(); + assert!(tmp_file_path_1.exists(), "Test file 1 hasn't been created"); + + File::create(&tmp_file_path_2).unwrap(); + assert!(tmp_file_path_2.exists(), "Test file 2 hasn't been created"); + + let tmp_path = TempPath::from_path(&tmp_file_path_1); + assert!( + tmp_file_path_1.exists(), + "Test file has been deleted before dropping TempPath" + ); + + drop(tmp_path); + assert!( + !tmp_file_path_1.exists(), + "Test file exists after dropping TempPath" + ); + assert!( + tmp_file_path_2.exists(), + "Test file 2 has been deleted before dropping TempDir" + ); +} + +#[test] +#[allow(unreachable_code)] +fn temp_path_from_argument_types() { + // This just has to compile + return; + + TempPath::from_path(""); + TempPath::from_path(String::new()); + TempPath::from_path(OsStr::new("")); + TempPath::from_path(OsString::new()); + TempPath::from_path(Path::new("")); + TempPath::from_path(PathBuf::new()); + TempPath::from_path(PathBuf::new().into_boxed_path()); +} + +#[test] fn test_write_after_close() { let path = NamedTempFile::new().unwrap().into_temp_path(); File::create(path).unwrap().write_all(b"test").unwrap(); |