use std::{
env,
fs::{self, File, OpenOptions, ReadDir},
io,
path::{Path, PathBuf},
};
pub struct TmpDir(PathBuf);
impl TmpDir {
pub fn new() -> Result<Self, io::Error> {
let path = env::temp_dir().join(uuid::Uuid::new_v4().to_string());
fs::create_dir(&path)?;
Ok(TmpDir(path))
}
pub fn path(&self) -> PathBuf {
self.0.clone()
}
pub fn unique_path(&self) -> PathBuf {
self.0.join(uuid::Uuid::new_v4().to_string())
}
pub fn write_file<P, C>(&self, path: P, contents: C) -> io::Result<()>
where
P: AsRef<Path>,
C: AsRef<[u8]>,
{
fs::write(self.0.join(path), contents)
}
pub fn read_file<P>(&self, path: P) -> io::Result<Vec<u8>>
where
P: AsRef<Path>,
{
fs::read(self.0.join(path))
}
pub fn create_dir<P>(&self, path: P) -> io::Result<()>
where
P: AsRef<Path>,
{
fs::create_dir(self.0.join(path))
}
pub fn create_dir_all<P>(&self, path: P) -> io::Result<()>
where
P: AsRef<Path>,
{
fs::create_dir_all(self.0.join(path))
}
pub fn create_file<P>(&self, path: P) -> io::Result<File>
where
P: AsRef<Path>,
{
File::create(self.0.join(path))
}
pub fn open_readable<P>(&self, path: P) -> io::Result<File>
where
P: AsRef<Path>,
{
File::open(self.0.join(path))
}
pub fn open_writable<P>(&self, path: P) -> io::Result<File>
where
P: AsRef<Path>,
{
OpenOptions::new().write(true).open(self.0.join(path))
}
pub fn open_with_opts<P>(&self, opts: &mut OpenOptions, path: P) -> io::Result<File>
where
P: AsRef<Path>,
{
opts.open(self.0.join(path))
}
pub fn metadata<P>(&self, path: P) -> io::Result<fs::Metadata>
where
P: AsRef<Path>,
{
self.0.join(path.as_ref()).metadata()
}
pub fn exists<P>(&self, path: P) -> bool
where
P: AsRef<Path>,
{
self.0.join(path.as_ref()).exists()
}
pub fn read_dir<P>(&self, path: P) -> io::Result<ReadDir>
where
P: AsRef<Path>,
{
fs::read_dir(&self.0.join(path))
}
pub fn remove_file<P>(&self, path: P) -> io::Result<()>
where
P: AsRef<Path>,
{
fs::remove_file(&self.0.join(path))
}
pub fn remove_dir<P>(&self, path: P) -> io::Result<()>
where
P: AsRef<Path>,
{
fs::remove_dir(&self.0.join(path))
}
pub fn remove_dir_all<P>(&self, path: P) -> io::Result<()>
where
P: AsRef<Path>,
{
fs::remove_dir_all(&self.0.join(path))
}
}
impl Drop for TmpDir {
fn drop(&mut self) {
fs::remove_dir_all(&self.0).ok();
}
}
pub struct TmpFile(PathBuf);
impl TmpFile {
pub fn new() -> Result<Self, io::Error> {
let path = env::temp_dir().join(uuid::Uuid::new_v4().to_string());
fs::write(&path, &[])?;
Ok(TmpFile(path))
}
pub fn path(&self) -> PathBuf {
self.0.clone()
}
pub fn write<C>(&self, contents: C) -> io::Result<()>
where
C: AsRef<[u8]>,
{
fs::write(&self.0, contents)
}
pub fn read(&self) -> io::Result<Vec<u8>> {
fs::read(&self.0)
}
pub fn open_readable(&self) -> io::Result<File> {
File::open(&self.0)
}
pub fn open_writable(&self) -> io::Result<File> {
OpenOptions::new().write(true).open(&self.0)
}
pub fn open_with_opts(&self, opts: &mut OpenOptions) -> io::Result<File> {
opts.open(&self.0)
}
}
impl Drop for TmpFile {
fn drop(&mut self) {
fs::remove_dir_all(&self.0).ok();
}
}