use std::future::Future;
use std::ops::DerefMut;
use crate::raw::*;
use crate::*;
pub type Composer = Box<dyn ComposeDyn>;
pub trait Compose: Unpin + Send + Sync {
fn compose<'a>(
&'a mut self,
path: &'a str,
args: OpRead,
) -> impl Future<Output = Result<()>> + MaybeSend + 'a;
fn close(&mut self) -> impl Future<Output = Result<Metadata>> + MaybeSend;
}
impl Compose for () {
async fn compose(&mut self, _: &str, _: OpRead) -> Result<()> {
Err(Error::new(
ErrorKind::Unsupported,
"output composer doesn't support compose",
))
}
async fn close(&mut self) -> Result<Metadata> {
Err(Error::new(
ErrorKind::Unsupported,
"output composer doesn't support close",
))
}
}
pub trait ComposeDyn: Unpin + Send + Sync {
fn compose_dyn<'a>(&'a mut self, path: &'a str, args: OpRead) -> BoxedFuture<'a, Result<()>>;
fn close_dyn(&mut self) -> BoxedFuture<'_, Result<Metadata>>;
}
impl<T: Compose + ?Sized> ComposeDyn for T {
fn compose_dyn<'a>(&'a mut self, path: &'a str, args: OpRead) -> BoxedFuture<'a, Result<()>> {
Box::pin(Compose::compose(self, path, args))
}
fn close_dyn(&mut self) -> BoxedFuture<'_, Result<Metadata>> {
Box::pin(self.close())
}
}
impl<T: ComposeDyn + ?Sized> Compose for Box<T> {
fn compose<'a>(
&'a mut self,
path: &'a str,
args: OpRead,
) -> impl Future<Output = Result<()>> + MaybeSend + 'a {
self.deref_mut().compose_dyn(path, args)
}
async fn close(&mut self) -> Result<Metadata> {
self.deref_mut().close_dyn().await
}
}