diem_temppath/
lib.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7
8#![forbid(unsafe_code)]
9
10use rand::RngCore;
11use std::{
12    fs, io,
13    path::{Path, PathBuf},
14};
15
16/// A simple wrapper for creating a temporary directory that is automatically
17/// deleted when it's dropped. Used in lieu of tempfile due to the large number
18/// of dependencies.
19#[derive(Debug, PartialEq)]
20pub struct TempPath {
21    path_buf: PathBuf,
22    persist: bool,
23}
24
25impl Drop for TempPath {
26    fn drop(&mut self) {
27        if !self.persist {
28            fs::remove_dir_all(&self.path_buf)
29                .or_else(|_| fs::remove_file(&self.path_buf))
30                .unwrap_or(());
31        }
32    }
33}
34
35impl TempPath {
36    /// Create new, uninitialized temporary path in the system temp directory.
37    pub fn new() -> Self { Self::new_with_temp_dir(std::env::temp_dir()) }
38
39    /// Create new, uninitialized temporary path in the specified directory.
40    pub fn new_with_temp_dir(temp_dir: PathBuf) -> Self {
41        let mut temppath = temp_dir;
42        let mut rng = rand::thread_rng();
43        let mut bytes = [0_u8; 16];
44        rng.fill_bytes(&mut bytes);
45        temppath.push(hex::encode(&bytes));
46
47        TempPath {
48            path_buf: temppath,
49            persist: false,
50        }
51    }
52
53    /// Return the underlying path to this temporary directory.
54    pub fn path(&self) -> &Path { &self.path_buf }
55
56    /// Keep the temp path
57    pub fn persist(&mut self) { self.persist = true; }
58
59    pub fn create_as_file(&self) -> io::Result<()> {
60        let mut builder = fs::OpenOptions::new();
61        builder.write(true).create_new(true);
62        builder.open(self.path())?;
63        Ok(())
64    }
65
66    pub fn create_as_dir(&self) -> io::Result<()> {
67        let builder = fs::DirBuilder::new();
68        builder.create(self.path())?;
69        Ok(())
70    }
71}
72
73impl std::convert::AsRef<Path> for TempPath {
74    fn as_ref(&self) -> &Path { self.path() }
75}
76
77impl Default for TempPath {
78    fn default() -> Self { Self::new() }
79}