1use crate::cfg_feature_std;
6use core::fmt::{Debug, Formatter};
7use std::path::{Path, PathBuf};
8
9pub struct TempFilePath {
10 path: PathBuf,
11}
12impl Debug for TempFilePath {
13 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
14 write!(f, "TempFile({})", self.path.display())
15 }
16}
17
18impl Drop for TempFilePath {
19 fn drop(&mut self) {
20 let _ = std::fs::remove_file(&self.path);
21 }
22}
23impl TempFilePath {
24 pub fn new<T: AsRef<Path>>(path: T) -> Self {
25 Self {
26 path: path.as_ref().into(),
27 }
28 }
29 pub fn get_path(&self) -> &PathBuf {
31 &self.path
32 }
33
34 cfg_feature_std! {
35 pub fn new_tempfile() -> Result<Self, std::io::Error> {
38 Self::new_tempfile_prefixed(".tmpirxf_")
39 }
40 pub fn new_tempfile_prefixed(prefix: &str) -> Result<Self, std::io::Error> {
43 let prefix = crate::fs::clean_filename(&prefix);
44 let tmpdir = std::env::temp_dir().join(format!("{prefix}{}", crate::uuid::UUID::new_random()));
45 let p = std::fs::OpenOptions::new()
46 .read(true)
47 .write(true)
48 .create_new(true)
49 .truncate(true)
50 .open(&tmpdir)?;
51 drop(p);
52 Ok(TempFilePath {
53 path: tmpdir
54 })
55 }
56 pub fn open(&self, opts: &std::fs::OpenOptions) -> Result<std::fs::File, std::io::Error> {
57 opts.open(&self.path)
58 }
59 pub fn open_write_buffered(&self, opts: &std::fs::OpenOptions) -> Result<std::io::BufWriter<std::fs::File>, std::io::Error> {
60 Ok(std::io::BufWriter::new(self.open(opts)?))
61 }
62 pub fn open_read_buffered(&self, opts: &std::fs::OpenOptions) -> Result<std::io::BufReader<std::fs::File>, std::io::Error> {
63 Ok(std::io::BufReader::new(self.open(opts)?))
64 }
65 }
66}
67macro_rules! impl_from {
68 ($dst:ident) => {
69 impl From<PathBuf> for $dst {
70 fn from(value: PathBuf) -> Self {
71 Self { path: value }
72 }
73 }
74 impl From<&PathBuf> for $dst {
75 fn from(value: &PathBuf) -> Self {
76 Self {
77 path: value.clone(),
78 }
79 }
80 }
81 };
82}
83impl_from!(TempFilePath);
84pub struct TempDirPath {
85 path: PathBuf,
86}
87impl Drop for TempDirPath {
88 fn drop(&mut self) {
89 let _ = std::fs::remove_dir_all(&self.path);
90 }
91}
92impl Debug for TempDirPath {
93 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
94 write!(f, "TempDir({})", self.path.display())
95 }
96}
97impl TempDirPath {
98 pub fn new<T: AsRef<Path>>(path: T) -> Self {
99 Self {
100 path: path.as_ref().into(),
101 }
102 }
103 pub fn get_path(&self) -> &PathBuf {
105 &self.path
106 }
107 cfg_feature_std! {
108 pub fn new_temp_dir() -> Result<Self, std::io::Error> {
112 Self::new_temp_dir_prefixed(".tmpirxd_")
113 }
114 pub fn new_temp_dir_prefixed(prefix: &str) -> Result<Self, std::io::Error> {
117 let prefix = crate::fs::clean_filename(&prefix);
118 let tmpdir = std::env::temp_dir().join(format!("{prefix}{}", crate::uuid::UUID::new_random()));
119 std::fs::create_dir_all(&tmpdir)?;
120 Ok(Self {
121 path: tmpdir
122 })
123 }
124 pub fn new_temp_file(&self) -> Result<TempFilePath, std::io::Error> {
127 let f = self.path.join(crate::uuid::UUID::new_random().to_string());
128 let p = std::fs::OpenOptions::new()
129 .read(true)
130 .write(true)
131 .create_new(true)
132 .truncate(true)
133 .open(&f)?;
134 drop(p);
135 Ok(TempFilePath {
136 path: f
137 })
138 }
139
140 }
141}
142impl_from!(TempDirPath);