compio-fs 0.12.0-rc.1

Filesystem IO for compio
Documentation
use std::{io, path::Path};

use compio_driver::ToSharedFd;
use windows_sys::Win32::Storage::FileSystem::FILE_FLAG_BACKUP_SEMANTICS;

use crate::{DirBuilder, File, Metadata, OpenOptions, metadata_at, symlink_metadata_at};

#[derive(Debug, Clone)]
pub struct Dir {
    inner: File,
}

impl Dir {
    pub async fn open(path: impl AsRef<Path>) -> io::Result<Self> {
        let file = OpenOptions::new()
            .read(true)
            .custom_flags(FILE_FLAG_BACKUP_SEMANTICS)
            .open(path)
            .await?;
        Ok(Dir { inner: file })
    }

    pub async fn open_file_with(
        &self,
        path: impl AsRef<Path>,
        options: &OpenOptions,
    ) -> io::Result<File> {
        options.open_at(&self.inner, path).await
    }

    pub async fn open_dir(&self, path: impl AsRef<Path>) -> io::Result<Self> {
        let file = self
            .open_file_with(
                path,
                OpenOptions::new()
                    .read(true)
                    .custom_flags(FILE_FLAG_BACKUP_SEMANTICS),
            )
            .await?;
        Ok(Dir { inner: file })
    }

    pub async fn create_dir_with(
        &self,
        path: impl AsRef<Path>,
        builder: &DirBuilder,
    ) -> io::Result<()> {
        builder.create_at(&self.inner, path.as_ref()).await
    }

    pub async fn dir_metadata(&self) -> io::Result<Metadata> {
        self.inner.metadata().await
    }

    pub async fn metadata(&self, path: impl AsRef<Path>) -> io::Result<Metadata> {
        metadata_at(&self.inner, path).await
    }

    pub async fn symlink_metadata(&self, path: impl AsRef<Path>) -> io::Result<Metadata> {
        symlink_metadata_at(&self.inner, path).await
    }

    pub async fn hard_link(
        &self,
        source: impl AsRef<Path>,
        target_dir: &Self,
        target: impl AsRef<Path>,
    ) -> io::Result<()> {
        let source = source.as_ref().to_path_buf();
        let target = target.as_ref().to_path_buf();
        crate::spawn_blocking_with2(
            self.to_shared_fd(),
            target_dir.to_shared_fd(),
            move |sdir, tdir| cap_primitives::fs::hard_link(sdir, &source, tdir, &target),
        )
        .await
    }

    pub async fn symlink_file(
        &self,
        original: impl AsRef<Path>,
        link: impl AsRef<Path>,
    ) -> io::Result<()> {
        let original = original.as_ref().to_path_buf();
        let link = link.as_ref().to_path_buf();
        crate::spawn_blocking_with(self.to_shared_fd(), move |dir| {
            cap_primitives::fs::symlink_file(&original, dir, &link)
        })
        .await
    }

    pub async fn symlink_dir(
        &self,
        original: impl AsRef<Path>,
        link: impl AsRef<Path>,
    ) -> io::Result<()> {
        let original = original.as_ref().to_path_buf();
        let link = link.as_ref().to_path_buf();
        crate::spawn_blocking_with(self.to_shared_fd(), move |dir| {
            cap_primitives::fs::symlink_dir(&original, dir, &link)
        })
        .await
    }

    pub async fn rename(
        &self,
        from: impl AsRef<Path>,
        to_dir: &Self,
        to: impl AsRef<Path>,
    ) -> io::Result<()> {
        let from = from.as_ref().to_path_buf();
        let to = to.as_ref().to_path_buf();
        crate::spawn_blocking_with2(
            self.to_shared_fd(),
            to_dir.to_shared_fd(),
            move |fdir, tdir| cap_primitives::fs::rename(fdir, &from, tdir, &to),
        )
        .await
    }

    pub async fn remove_file(&self, path: impl AsRef<Path>) -> io::Result<()> {
        let path = path.as_ref().to_path_buf();
        crate::spawn_blocking_with(self.to_shared_fd(), move |dir| {
            cap_primitives::fs::remove_file(dir, &path)
        })
        .await
    }

    pub async fn remove_dir(&self, path: impl AsRef<Path>) -> io::Result<()> {
        let path = path.as_ref().to_path_buf();
        crate::spawn_blocking_with(self.to_shared_fd(), move |dir| {
            cap_primitives::fs::remove_dir(dir, &path)
        })
        .await
    }
}

compio_driver::impl_raw_fd!(Dir, std::fs::File, inner);