mod dir;
mod dir_builder;
mod file;
mod metadata;
mod open_options;
mod read_dir;
mod read_link;
mod remove_dir_all;
mod symlink;
use std::path::Path;
use crate::{
buf::Slice,
driver::ops::Op,
io::{AsyncReadAtExt, AsyncWriteAt},
};
pub use dir::*;
pub use dir_builder::*;
pub use file::*;
pub use metadata::*;
pub use open_options::*;
pub use read_dir::*;
pub use read_link::*;
pub use remove_dir_all::*;
pub use symlink::*;
pub(crate) async fn asyncify<F, T>(operation: F) -> std::io::Result<T>
where
F: FnOnce() -> std::io::Result<T> + Send + 'static,
T: Send + 'static,
{
match crate::runtime::spawn_blocking(operation).await {
Ok(result) => result,
Err(error) if error.is_panic() => std::panic::resume_unwind(error.into_panic()),
Err(error) => Err(std::io::Error::other(error.to_string())),
}
}
pub async fn read(path: impl AsRef<Path>) -> std::io::Result<Vec<u8>> {
let file = file::File::open(path).await?;
let (result, contents) = file.read_to_end_at(Vec::new(), 0).await.into_parts();
result?;
Ok(contents)
}
pub async fn write(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> std::io::Result<()> {
let mut file = file::File::create(path).await?;
let mut buf = contents.as_ref().to_vec();
let len = buf.len();
let mut offset = 0usize;
while offset < len {
let slice = Slice::new(buf, offset, len);
let (res, slice) = file.write_at(slice, offset as u64).await.into_parts();
buf = slice.into_inner();
let n = res?;
if n == 0 {
return Err(std::io::Error::from(std::io::ErrorKind::WriteZero));
}
offset += n;
}
file.close().await
}
pub async fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> std::io::Result<()> {
Op::rename(from, to)?.await
}
pub async fn remove_file(path: impl AsRef<Path>) -> std::io::Result<()> {
Op::remove_file(path.as_ref())?.await
}
pub async fn remove_dir(path: impl AsRef<Path>) -> std::io::Result<()> {
Op::remove_dir(path.as_ref())?.await
}
pub async fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> std::io::Result<()> {
Op::hardlink(original, link)?.await
}
pub async fn set_permissions(path: impl AsRef<Path>, perm: metadata::Permissions) -> std::io::Result<()> {
let path = path.as_ref().to_owned();
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mode = perm.mode();
asyncify(move || {
rustix::fs::chmod(&path, rustix::fs::Mode::from_raw_mode(mode as _)).map_err(std::io::Error::from)
})
.await
}
#[cfg(windows)]
{
let readonly = perm.readonly();
asyncify(move || {
let mut permissions = std::fs::metadata(&path)?.permissions();
permissions.set_readonly(readonly);
std::fs::set_permissions(path, permissions)
})
.await
}
}