puffin/puffin_manager/
file_accessor.rsuse async_trait::async_trait;
use common_base::range_read::{FileReader, SizeAwareRangeReader};
use common_test_util::temp_dir::{create_temp_dir, TempDir};
use futures::AsyncWrite;
use tokio::fs::File;
use tokio_util::compat::{Compat, TokioAsyncReadCompatExt};
use crate::error::Result;
#[async_trait]
#[auto_impl::auto_impl(Arc)]
pub trait PuffinFileAccessor: Send + Sync + 'static {
type Reader: SizeAwareRangeReader + Sync;
type Writer: AsyncWrite + Unpin + Send;
type FileHandle: ToString + Clone + Send + Sync;
async fn reader(&self, handle: &Self::FileHandle) -> Result<Self::Reader>;
async fn writer(&self, handle: &Self::FileHandle) -> Result<Self::Writer>;
}
pub struct MockFileAccessor {
tempdir: TempDir,
}
impl MockFileAccessor {
pub fn new(prefix: &str) -> Self {
let tempdir = create_temp_dir(prefix);
Self { tempdir }
}
}
#[async_trait]
impl PuffinFileAccessor for MockFileAccessor {
type Reader = FileReader;
type Writer = Compat<File>;
type FileHandle = String;
async fn reader(&self, handle: &String) -> Result<Self::Reader> {
Ok(FileReader::new(self.tempdir.path().join(handle))
.await
.unwrap())
}
async fn writer(&self, handle: &String) -> Result<Self::Writer> {
let p = self.tempdir.path().join(handle);
if let Some(p) = p.parent() {
if !tokio::fs::try_exists(p).await.unwrap() {
tokio::fs::create_dir_all(p).await.unwrap();
}
}
let f = tokio::fs::File::create(p).await.unwrap();
Ok(f.compat())
}
}