use std::future::Future;
use std::ops::DerefMut;
use crate::raw::*;
use crate::*;
pub type Writer = Box<dyn WriteDyn>;
pub trait Write: Unpin + Send + Sync {
fn write(&mut self, bs: Buffer) -> impl Future<Output = Result<()>> + MaybeSend;
fn copy_from(
&mut self,
_path: &str,
_args: OpRead,
_range: BytesRange,
) -> impl Future<Output = Result<()>> + MaybeSend {
async {
Err(Error::new(
ErrorKind::Unsupported,
"writer doesn't support native copy",
))
}
}
fn close(&mut self) -> impl Future<Output = Result<Metadata>> + MaybeSend;
fn abort(&mut self) -> impl Future<Output = Result<()>> + MaybeSend;
}
impl Write for () {
async fn write(&mut self, _: Buffer) -> Result<()> {
unimplemented!("write is required to be implemented for oio::Write")
}
async fn close(&mut self) -> Result<Metadata> {
Err(Error::new(
ErrorKind::Unsupported,
"output writer doesn't support close",
))
}
async fn abort(&mut self) -> Result<()> {
Err(Error::new(
ErrorKind::Unsupported,
"output writer doesn't support abort",
))
}
}
pub trait WriteDyn: Unpin + Send + Sync {
fn write_dyn(&mut self, bs: Buffer) -> BoxedFuture<'_, Result<()>>;
fn copy_from_dyn<'a>(
&'a mut self,
path: &'a str,
args: OpRead,
range: BytesRange,
) -> BoxedFuture<'a, Result<()>>;
fn close_dyn(&mut self) -> BoxedFuture<'_, Result<Metadata>>;
fn abort_dyn(&mut self) -> BoxedFuture<'_, Result<()>>;
}
impl<T: Write + ?Sized> WriteDyn for T {
fn write_dyn(&mut self, bs: Buffer) -> BoxedFuture<'_, Result<()>> {
Box::pin(self.write(bs))
}
fn copy_from_dyn<'a>(
&'a mut self,
path: &'a str,
args: OpRead,
range: BytesRange,
) -> BoxedFuture<'a, Result<()>> {
Box::pin(self.copy_from(path, args, range))
}
fn close_dyn(&mut self) -> BoxedFuture<'_, Result<Metadata>> {
Box::pin(self.close())
}
fn abort_dyn(&mut self) -> BoxedFuture<'_, Result<()>> {
Box::pin(self.abort())
}
}
impl<T: WriteDyn + ?Sized> Write for Box<T> {
async fn write(&mut self, bs: Buffer) -> Result<()> {
self.deref_mut().write_dyn(bs).await
}
async fn copy_from(&mut self, path: &str, args: OpRead, range: BytesRange) -> Result<()> {
self.deref_mut().copy_from_dyn(path, args, range).await
}
async fn close(&mut self) -> Result<Metadata> {
self.deref_mut().close_dyn().await
}
async fn abort(&mut self) -> Result<()> {
self.deref_mut().abort_dyn().await
}
}