use std::path::{
Path,
PathBuf,
};
use crate::{
AsyncFile,
FsError,
Operation,
};
pub struct TempDir {
path: PathBuf,
}
impl TempDir {
pub async fn create(root: impl AsRef<Path>) -> Result<Self, FsError> {
let root = root.as_ref().to_owned();
tokio::fs::create_dir_all(&root)
.await
.map_err(|error| FsError::io(Operation::Directory, &root, error))?;
let path = root.join(format!("tmp-{}", uuid::Uuid::new_v4()));
tokio::fs::create_dir(&path)
.await
.map_err(|error| FsError::io(Operation::Directory, &path, error))?;
Ok(Self { path })
}
#[must_use]
pub fn path(&self) -> &Path {
&self.path
}
pub async fn remove(self) -> Result<(), FsError> {
crate::directory::remove_dir_all(&self.path).await
}
}
pub struct TempFile {
path: PathBuf,
file: Option<AsyncFile>,
}
impl TempFile {
pub async fn create(root: impl AsRef<Path>) -> Result<Self, FsError> {
let root = root.as_ref().to_owned();
tokio::fs::create_dir_all(&root)
.await
.map_err(|error| FsError::io(Operation::Directory, &root, error))?;
let path = root.join(format!("tmp-file-{}", uuid::Uuid::new_v4()));
let file = AsyncFile::create_new(&path).await?;
Ok(Self {
path,
file: Some(file),
})
}
#[must_use]
pub fn path(&self) -> &Path {
&self.path
}
pub fn file_mut(&mut self) -> Result<&mut AsyncFile, FsError> {
self.file.as_mut().ok_or_else(|| {
FsError::InvalidRequest("temporary file handle was already closed".to_owned())
})
}
pub async fn remove(mut self) -> Result<(), FsError> {
self.file.take();
tokio::fs::remove_file(&self.path)
.await
.map_err(|error| FsError::io(Operation::Write, &self.path, error))
}
pub fn persist(mut self) -> PathBuf {
self.file.take();
self.path
}
}