maketemp/
lib.rs

1//! Create temporary directory and file.
2//! 
3//! - No dependencies.
4//! - Create in any directory.
5//! - Add prefix and suffix in the name.
6//! - Auto deletion.
7//! 
8//! ```rust
9//! use maketemp::TempDir;
10//! use std::path::Path;
11//! 
12//! fn main() {
13//!     let p;
14//!     
15//!     {
16//!         // create temporary directory.
17//!         let dir = TempDir::open();
18//!         p = dir.path().to_string();
19//!         
20//!         // true.
21//!         println!("path {} exists: {} ",&p,Path::new(&p).exists());
22//!         
23//!         // delete `dir` automatically here.
24//!     }
25//!     
26//!     // false.
27//!     println!("path: {} exists: {}",&p,Path::new(&p).exists());
28//! }
29//! ```
30
31use std::{
32    path::Path,
33    time::{ Duration,SystemTime,UNIX_EPOCH }
34};
35
36fn make_path<P:AsRef<Path>,N1:AsRef<str>,N2:AsRef<str>>(dir:P,prefix:N1,suffix:N2) -> std::path::PathBuf {
37    loop {
38        let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_micros();
39        let p = dir.as_ref().join(format!("{}{}{}",prefix.as_ref(),now,suffix.as_ref()));
40        if !p.exists() { return p; }
41        std::thread::sleep(Duration::from_micros(1));
42    };
43}
44
45/// Temporary Directory.
46pub struct TempDir {
47    path:String
48}
49
50impl TempDir {
51    /// Create temporary directory in user temporary directory.
52    pub fn open() -> Result<Self,String> {
53        let tmpdir = std::env::temp_dir();
54        
55        let path = make_path(tmpdir,"temp-","");
56        match std::fs::create_dir(&path) {
57            Ok(()) => {
58                Ok(Self { path:path.as_os_str().to_str().unwrap().to_string() })
59            },
60            Err(err) => { Err(format!("{}",err)) }
61        }
62    }
63    /// Create temporary directory in the given directory.
64    /// 
65    /// - `dir`    - directory path to create.
66    /// - `prefix` - prefix name.
67    pub fn open_with<P:AsRef<Path>,N:AsRef<str>>(dir:P,prefix:N) -> Result<Self,String> {
68        let path = make_path(dir,prefix,"");
69        match std::fs::create_dir(&path) {
70            Ok(()) => {
71                Ok(Self { path:path.as_os_str().to_str().unwrap().to_string() })
72            },
73            Err(err) => { Err(format!("{}",err)) }
74        }
75    }
76    /// Return directory path.
77    pub fn path(&self) -> &str {
78        self.path.as_str()
79    }
80}
81
82impl Drop for TempDir {
83    fn drop(&mut self) {
84        let p = Path::new(&self.path);
85        if p.exists() {
86            std::fs::remove_dir_all(p).unwrap();
87        }
88    }
89}
90
91/// Temporary File.
92pub struct TempFile {
93    path:String
94}
95
96impl TempFile {
97    /// Create temporary file in user temporary directory.
98    pub fn open() -> Result<Self,String> {
99        let tmpdir = std::env::temp_dir();
100        
101        let path = make_path(tmpdir,"","");
102        {
103            let _f = match std::fs::OpenOptions::new().create_new(true).write(true).open(&path) {
104                Ok(v) => { v },
105                Err(err) => { return Err(format!("{}",err)); },
106            };
107        }
108        Ok(Self { path:path.as_os_str().to_str().unwrap().to_string() })
109    }
110    /// Create temporary file in the given directory.
111    /// 
112    /// - `dir`    - directory path to create.
113    /// - `suffix` - suffix name.
114    pub fn open_with<P:AsRef<Path>,N1:AsRef<str>,N2:AsRef<str>>(dir:P,prefix:N1,suffix:N2) -> Result<Self,String> {
115        let path = make_path(dir,prefix,suffix);
116        {
117            let _f = match std::fs::OpenOptions::new().create_new(true).write(true).open(&path) {
118                Ok(v) => { v },
119                Err(err) => { return Err(format!("{}",err)); },
120            };
121        }
122        Ok(Self { path:path.as_os_str().to_str().unwrap().to_string() })
123    }
124    /// Return directory path.
125    pub fn path(&self) -> &str {
126        self.path.as_str()
127    }
128}
129
130impl Drop for TempFile {
131    fn drop(&mut self) {
132        let p = Path::new(&self.path);
133        if p.exists() {
134            std::fs::remove_file(&self.path).unwrap();
135        }
136    }
137}