use std::future::Future;
use crate::raw::*;
use crate::*;
pub trait AppendWrite: Send + Sync + Unpin + 'static {
fn offset(&self) -> impl Future<Output = Result<u64>> + MaybeSend;
fn append(
&self,
offset: u64,
size: u64,
body: Buffer,
) -> impl Future<Output = Result<Metadata>> + MaybeSend;
}
pub struct AppendWriter<W: AppendWrite> {
inner: W,
offset: Option<u64>,
meta: Metadata,
}
impl<W: AppendWrite> AppendWriter<W> {
pub fn new(inner: W) -> Self {
Self {
inner,
offset: None,
meta: Metadata::default(),
}
}
}
impl<W> oio::Write for AppendWriter<W>
where
W: AppendWrite,
{
async fn write(&mut self, bs: Buffer) -> Result<()> {
let offset = match self.offset {
Some(offset) => offset,
None => {
let offset = self.inner.offset().await?;
self.offset = Some(offset);
offset
}
};
let size = bs.len();
self.meta = self.inner.append(offset, size as u64, bs).await?;
self.offset = Some(offset + size as u64);
Ok(())
}
async fn close(&mut self) -> Result<Metadata> {
self.meta
.set_content_length(self.offset.unwrap_or_default());
Ok(self.meta.clone())
}
async fn abort(&mut self) -> Result<()> {
Ok(())
}
}