#![cfg(feature = "tokio")]
use crate::Phazer;
use std::marker::PhantomData;
use std::pin::Pin;
use tokio::fs::{File, OpenOptions};
use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite};
impl<'cs> Phazer<'cs> {
pub async fn tokio_writer<'a>(&'a self) -> std::io::Result<TokioPhazerWriter> {
let mut options = OpenOptions::new();
options.read(true).write(true);
if self.first_writer() {
options.truncate(true).create(true);
}
let phase1 = options.open(&self.working_path).await?;
Ok(TokioPhazerWriter {
phase1,
_parent: PhantomData::<&'a Self>,
})
}
}
pub struct TokioPhazerWriter<'a, 'cs> {
phase1: File,
_parent: PhantomData<&'a Phazer<'cs>>,
}
impl<'a, 'cs> AsyncRead for TokioPhazerWriter<'a, 'cs> {
fn poll_read(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
buf: &mut tokio::io::ReadBuf<'_>,
) -> std::task::Poll<std::io::Result<()>> {
let mut pp: Pin<Box<&mut File>> = Pin::from(Box::new(&mut self.phase1));
pp.as_mut().poll_read(cx, buf)
}
}
impl<'a, 'cs> AsyncSeek for TokioPhazerWriter<'a, 'cs> {
fn poll_complete(
mut self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<std::io::Result<u64>> {
let mut pp: Pin<Box<&mut File>> = Pin::from(Box::new(&mut self.phase1));
pp.as_mut().poll_complete(cx)
}
fn start_seek(mut self: Pin<&mut Self>, position: std::io::SeekFrom) -> std::io::Result<()> {
let mut pp: Pin<Box<&mut File>> = Pin::from(Box::new(&mut self.phase1));
pp.as_mut().start_seek(position)
}
}
impl<'a, 'cs> AsyncWrite for TokioPhazerWriter<'a, 'cs> {
fn poll_flush(
mut self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Result<(), std::io::Error>> {
let mut pp: Pin<Box<&mut File>> = Pin::from(Box::new(&mut self.phase1));
pp.as_mut().poll_flush(cx)
}
fn poll_shutdown(
mut self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Result<(), std::io::Error>> {
let mut pp: Pin<Box<&mut File>> = Pin::from(Box::new(&mut self.phase1));
pp.as_mut().poll_shutdown(cx)
}
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
buf: &[u8],
) -> std::task::Poll<Result<usize, std::io::Error>> {
let mut pp: Pin<Box<&mut File>> = Pin::from(Box::new(&mut self.phase1));
pp.as_mut().poll_write(cx, buf)
}
}
impl<'a, 'cs> Drop for TokioPhazerWriter<'a, 'cs> {
fn drop(&mut self) {}
}