use std::io;
use std::ops::Range;
use async_trait::async_trait;
use rusoto_core::ByteStream;
use tantivy::directory::OwnedBytes;
#[async_trait]
pub trait PutPayload: PutPayloadClone + Send + Sync {
fn len(&self) -> u64;
async fn range_byte_stream(&self, range: Range<u64>) -> io::Result<ByteStream>;
async fn byte_stream(&self) -> io::Result<ByteStream> {
let total_len = self.len();
let range = 0..total_len;
self.range_byte_stream(range).await
}
async fn read_all(&self) -> io::Result<OwnedBytes> {
let total_len = self.len();
let range = 0..total_len;
let mut reader = self.range_byte_stream(range).await?.into_async_read();
let mut data: Vec<u8> = Vec::with_capacity(total_len as usize);
tokio::io::copy(&mut reader, &mut data).await?;
Ok(OwnedBytes::new(data))
}
}
pub trait PutPayloadClone {
fn box_clone(&self) -> Box<dyn PutPayload>;
}
impl<T> PutPayloadClone for T
where T: 'static + PutPayload + Clone
{
fn box_clone(&self) -> Box<dyn PutPayload> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn PutPayload> {
fn clone(&self) -> Box<dyn PutPayload> {
self.box_clone()
}
}
#[async_trait]
impl PutPayload for Vec<u8> {
fn len(&self) -> u64 {
self.len() as u64
}
async fn range_byte_stream(&self, range: Range<u64>) -> io::Result<ByteStream> {
Ok(ByteStream::from(
(&self[range.start as usize..range.end as usize]).to_vec(),
))
}
}