use std::fs::{Metadata, Permissions};
use std::io;
use std::path::{Path, PathBuf};
use crate::io::Handle;
pub(crate) use crate::rt::blocking::call as blocking;
pub async fn read(path: impl AsRef<Path>) -> io::Result<Vec<u8>> {
let path = path.as_ref().to_path_buf();
blocking(move || std::fs::read(path)).await
}
pub async fn read_to_string(path: impl AsRef<Path>) -> io::Result<String> {
let path = path.as_ref().to_path_buf();
blocking(move || std::fs::read_to_string(path)).await
}
pub async fn write(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> io::Result<()> {
let (path, contents) = (path.as_ref().to_path_buf(), contents.as_ref().to_vec());
blocking(move || std::fs::write(path, contents)).await
}
pub async fn metadata(path: impl AsRef<Path>) -> io::Result<Metadata> {
let path = path.as_ref().to_path_buf();
blocking(move || std::fs::metadata(path)).await
}
pub async fn symlink_metadata(path: impl AsRef<Path>) -> io::Result<Metadata> {
let path = path.as_ref().to_path_buf();
blocking(move || std::fs::symlink_metadata(path)).await
}
pub async fn try_exists(path: impl AsRef<Path>) -> io::Result<bool> {
let path = path.as_ref().to_path_buf();
blocking(move || path.try_exists()).await
}
pub async fn create_dir(path: impl AsRef<Path>) -> io::Result<()> {
let path = path.as_ref().to_path_buf();
blocking(move || std::fs::create_dir(path)).await
}
pub async fn create_dir_all(path: impl AsRef<Path>) -> io::Result<()> {
let path = path.as_ref().to_path_buf();
blocking(move || std::fs::create_dir_all(path)).await
}
pub async fn remove_file(path: impl AsRef<Path>) -> io::Result<()> {
let path = path.as_ref().to_path_buf();
blocking(move || std::fs::remove_file(path)).await
}
pub async fn remove_dir(path: impl AsRef<Path>) -> io::Result<()> {
let path = path.as_ref().to_path_buf();
blocking(move || std::fs::remove_dir(path)).await
}
pub async fn remove_dir_all(path: impl AsRef<Path>) -> io::Result<()> {
let path = path.as_ref().to_path_buf();
blocking(move || std::fs::remove_dir_all(path)).await
}
pub async fn rename(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()> {
let (from, to) = (from.as_ref().to_path_buf(), to.as_ref().to_path_buf());
blocking(move || std::fs::rename(from, to)).await
}
pub async fn copy(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<u64> {
let (from, to) = (from.as_ref().to_path_buf(), to.as_ref().to_path_buf());
blocking(move || std::fs::copy(from, to)).await
}
pub async fn hard_link(original: impl AsRef<Path>, link: impl AsRef<Path>) -> io::Result<()> {
let (original, link) = (original.as_ref().to_path_buf(), link.as_ref().to_path_buf());
blocking(move || std::fs::hard_link(original, link)).await
}
#[cfg(unix)]
pub async fn symlink(original: impl AsRef<Path>, link: impl AsRef<Path>) -> io::Result<()> {
let (original, link) = (original.as_ref().to_path_buf(), link.as_ref().to_path_buf());
blocking(move || std::os::unix::fs::symlink(original, link)).await
}
#[cfg(windows)]
pub async fn symlink_file(original: impl AsRef<Path>, link: impl AsRef<Path>) -> io::Result<()> {
let (original, link) = (original.as_ref().to_path_buf(), link.as_ref().to_path_buf());
blocking(move || std::os::windows::fs::symlink_file(original, link)).await
}
#[cfg(windows)]
pub async fn symlink_dir(original: impl AsRef<Path>, link: impl AsRef<Path>) -> io::Result<()> {
let (original, link) = (original.as_ref().to_path_buf(), link.as_ref().to_path_buf());
blocking(move || std::os::windows::fs::symlink_dir(original, link)).await
}
pub async fn read_link(path: impl AsRef<Path>) -> io::Result<PathBuf> {
let path = path.as_ref().to_path_buf();
blocking(move || std::fs::read_link(path)).await
}
pub async fn canonicalize(path: impl AsRef<Path>) -> io::Result<PathBuf> {
let path = path.as_ref().to_path_buf();
blocking(move || std::fs::canonicalize(path)).await
}
pub async fn set_permissions(path: impl AsRef<Path>, perm: Permissions) -> io::Result<()> {
let path = path.as_ref().to_path_buf();
blocking(move || std::fs::set_permissions(path, perm)).await
}
#[derive(Clone, Debug)]
pub struct OpenOptions(std::fs::OpenOptions);
impl Default for OpenOptions {
fn default() -> Self {
Self::new()
}
}
impl OpenOptions {
pub fn new() -> Self {
Self(std::fs::OpenOptions::new())
}
pub fn read(&mut self, read: bool) -> &mut Self {
self.0.read(read);
self
}
pub fn write(&mut self, write: bool) -> &mut Self {
self.0.write(write);
self
}
pub fn append(&mut self, append: bool) -> &mut Self {
self.0.append(append);
self
}
pub fn truncate(&mut self, truncate: bool) -> &mut Self {
self.0.truncate(truncate);
self
}
pub fn create(&mut self, create: bool) -> &mut Self {
self.0.create(create);
self
}
pub fn create_new(&mut self, create_new: bool) -> &mut Self {
self.0.create_new(create_new);
self
}
#[cfg(unix)]
pub fn mode(&mut self, mode: u32) -> &mut Self {
std::os::unix::fs::OpenOptionsExt::mode(&mut self.0, mode);
self
}
#[cfg(unix)]
pub fn custom_flags(&mut self, flags: i32) -> &mut Self {
std::os::unix::fs::OpenOptionsExt::custom_flags(&mut self.0, flags);
self
}
#[cfg(windows)]
pub fn access_mode(&mut self, access: u32) -> &mut Self {
std::os::windows::fs::OpenOptionsExt::access_mode(&mut self.0, access);
self
}
#[cfg(windows)]
pub fn share_mode(&mut self, share: u32) -> &mut Self {
std::os::windows::fs::OpenOptionsExt::share_mode(&mut self.0, share);
self
}
#[cfg(windows)]
pub fn custom_flags(&mut self, flags: u32) -> &mut Self {
std::os::windows::fs::OpenOptionsExt::custom_flags(&mut self.0, flags);
self
}
#[cfg(windows)]
pub fn attributes(&mut self, attributes: u32) -> &mut Self {
std::os::windows::fs::OpenOptionsExt::attributes(&mut self.0, attributes);
self
}
#[cfg(windows)]
pub fn security_qos_flags(&mut self, flags: u32) -> &mut Self {
std::os::windows::fs::OpenOptionsExt::security_qos_flags(&mut self.0, flags);
self
}
pub async fn open(&self, path: impl AsRef<Path>) -> io::Result<Handle<std::fs::File>> {
let (options, path) = (self.0.clone(), path.as_ref().to_path_buf());
let file = blocking(move || options.open(path)).await?;
Handle::new(file)
}
}
impl From<std::fs::OpenOptions> for OpenOptions {
fn from(options: std::fs::OpenOptions) -> Self {
Self(options)
}
}
#[derive(Debug, Default)]
pub struct DirBuilder {
recursive: bool,
#[cfg(unix)]
mode: Option<u32>,
}
impl DirBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn recursive(&mut self, recursive: bool) -> &mut Self {
self.recursive = recursive;
self
}
#[cfg(unix)]
pub fn mode(&mut self, mode: u32) -> &mut Self {
self.mode = Some(mode);
self
}
pub async fn create(&self, path: impl AsRef<Path>) -> io::Result<()> {
let mut builder = std::fs::DirBuilder::new();
builder.recursive(self.recursive);
#[cfg(unix)]
if let Some(mode) = self.mode {
std::os::unix::fs::DirBuilderExt::mode(&mut builder, mode);
}
let path = path.as_ref().to_path_buf();
blocking(move || builder.create(path)).await
}
}