use std::future::Future;
use std::io;
use std::path::PathBuf;
use std::pin::Pin;
use std::task::{Context, Poll};
pub use tokio::fs::File as DtactFile;
pub struct DtactCompat<T>(T);
impl<T> DtactCompat<T> {
pub const fn new(inner: T) -> Self {
Self(inner)
}
pub fn into_inner(self) -> T {
self.0
}
pub const fn get_ref(&self) -> &T {
&self.0
}
pub const fn get_mut(&mut self) -> &mut T {
&mut self.0
}
}
pub trait DtactCompatExt: Sized {
fn compat(self) -> DtactCompat<Self>;
}
impl DtactCompatExt for DtactFile {
fn compat(self) -> DtactCompat<Self> {
DtactCompat(self)
}
}
impl<F: Future> Future for DtactCompat<F> {
type Output = F::Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let inner = unsafe { self.map_unchecked_mut(|s| &mut s.0) };
inner.poll(cx)
}
}
impl futures_io::AsyncRead for DtactCompat<DtactFile> {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
let this = unsafe { self.map_unchecked_mut(|s| &mut s.0) };
let mut read_buf = tokio::io::ReadBuf::new(buf);
match tokio::io::AsyncRead::poll_read(this, cx, &mut read_buf) {
Poll::Ready(Ok(())) => Poll::Ready(Ok(read_buf.filled().len())),
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
Poll::Pending => Poll::Pending,
}
}
}
impl futures_io::AsyncWrite for DtactCompat<DtactFile> {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
let this = unsafe { self.map_unchecked_mut(|s| &mut s.0) };
tokio::io::AsyncWrite::poll_write(this, cx, buf)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
let this = unsafe { self.map_unchecked_mut(|s| &mut s.0) };
tokio::io::AsyncWrite::poll_flush(this, cx)
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
let this = unsafe { self.map_unchecked_mut(|s| &mut s.0) };
tokio::io::AsyncWrite::poll_shutdown(this, cx)
}
}
pub async fn metadata(path: impl Into<PathBuf>) -> io::Result<std::fs::Metadata> {
tokio::fs::metadata(path.into()).await
}
pub async fn read_dir(path: impl Into<PathBuf>) -> io::Result<Vec<tokio::fs::DirEntry>> {
let mut rd = tokio::fs::read_dir(path.into()).await?;
let mut out = Vec::new();
while let Some(entry) = rd.next_entry().await? {
out.push(entry);
}
Ok(out)
}
pub async fn create_dir_all(path: impl Into<PathBuf>) -> io::Result<()> {
tokio::fs::create_dir_all(path.into()).await
}
pub async fn remove_file(path: impl Into<PathBuf>) -> io::Result<()> {
tokio::fs::remove_file(path.into()).await
}
pub async fn canonicalize(path: impl Into<PathBuf>) -> io::Result<PathBuf> {
tokio::fs::canonicalize(path.into()).await
}
pub async fn copy(from: impl Into<PathBuf>, to: impl Into<PathBuf>) -> io::Result<u64> {
tokio::fs::copy(from.into(), to.into()).await
}
pub async fn create_dir(path: impl Into<PathBuf>) -> io::Result<()> {
tokio::fs::create_dir(path.into()).await
}
pub async fn hard_link(src: impl Into<PathBuf>, dst: impl Into<PathBuf>) -> io::Result<()> {
tokio::fs::hard_link(src.into(), dst.into()).await
}
pub async fn read(path: impl Into<PathBuf>) -> io::Result<Vec<u8>> {
tokio::fs::read(path.into()).await
}
pub async fn read_link(path: impl Into<PathBuf>) -> io::Result<PathBuf> {
tokio::fs::read_link(path.into()).await
}
pub async fn read_to_string(path: impl Into<PathBuf>) -> io::Result<String> {
tokio::fs::read_to_string(path.into()).await
}
pub async fn remove_dir(path: impl Into<PathBuf>) -> io::Result<()> {
tokio::fs::remove_dir(path.into()).await
}
pub async fn remove_dir_all(path: impl Into<PathBuf>) -> io::Result<()> {
tokio::fs::remove_dir_all(path.into()).await
}
pub async fn rename(from: impl Into<PathBuf>, to: impl Into<PathBuf>) -> io::Result<()> {
tokio::fs::rename(from.into(), to.into()).await
}
pub async fn set_permissions(
path: impl Into<PathBuf>,
perm: std::fs::Permissions,
) -> io::Result<()> {
tokio::fs::set_permissions(path.into(), perm).await
}
#[cfg(unix)]
pub async fn symlink(src: impl Into<PathBuf>, dst: impl Into<PathBuf>) -> io::Result<()> {
tokio::fs::symlink(src.into(), dst.into()).await
}
#[cfg(windows)]
pub async fn symlink_dir(src: impl Into<PathBuf>, dst: impl Into<PathBuf>) -> io::Result<()> {
tokio::fs::symlink_dir(src.into(), dst.into()).await
}
#[cfg(windows)]
pub async fn symlink_file(src: impl Into<PathBuf>, dst: impl Into<PathBuf>) -> io::Result<()> {
tokio::fs::symlink_file(src.into(), dst.into()).await
}
pub async fn symlink_metadata(path: impl Into<PathBuf>) -> io::Result<std::fs::Metadata> {
tokio::fs::symlink_metadata(path.into()).await
}
pub async fn try_exists(path: impl Into<PathBuf>) -> io::Result<bool> {
tokio::fs::try_exists(path.into()).await
}
pub async fn write(path: impl Into<PathBuf>, contents: impl AsRef<[u8]>) -> io::Result<()> {
tokio::fs::write(path.into(), contents).await
}