1use 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
45pub struct TempDir {
47 path:String
48}
49
50impl TempDir {
51 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 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 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
91pub struct TempFile {
93 path:String
94}
95
96impl TempFile {
97 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 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 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}