use std::{io, ops::Range, path::Path, sync::Arc};
use async_trait::async_trait;
use tantivy::{
Directory, HasLen,
directory::{
FileHandle, RamDirectory, WatchCallback, WatchHandle, WritePtr,
error::{DeleteError, OpenReadError, OpenWriteError},
},
};
use tantivy_common::OwnedBytes;
#[derive(Clone, Debug)]
pub struct FailingDirectory(pub RamDirectory);
#[derive(Debug)]
struct FailingHandle {
len: usize,
path: std::path::PathBuf,
}
impl Directory for FailingDirectory {
fn get_file_handle(&self, path: &Path) -> Result<Arc<dyn FileHandle>, OpenReadError> {
let file = self.0.open_read(path)?;
let len = file.len();
let path = path.into();
Ok(Arc::new(FailingHandle { len, path }))
}
fn delete(&self, path: &Path) -> Result<(), DeleteError> {
self.0.delete(path)
}
fn exists(&self, path: &Path) -> Result<bool, OpenReadError> {
self.0.exists(path)
}
fn open_write(&self, path: &Path) -> Result<WritePtr, OpenWriteError> {
self.0.open_write(path)
}
fn atomic_read(&self, path: &Path) -> Result<Vec<u8>, OpenReadError> {
self.0.atomic_read(path)
}
fn atomic_write(&self, path: &Path, data: &[u8]) -> io::Result<()> {
self.0.atomic_write(path, data)
}
fn sync_directory(&self) -> io::Result<()> {
self.0.sync_directory()
}
fn watch(&self, cb: WatchCallback) -> tantivy::Result<WatchHandle> {
self.0.watch(cb)
}
}
#[async_trait]
impl FileHandle for FailingHandle {
fn read_bytes(&self, range: Range<usize>) -> io::Result<OwnedBytes> {
panic!(
"unexpected read of {:?} at {:?} (file length {})",
self.path, range, self.len,
);
}
async fn read_bytes_async(&self, range: Range<usize>) -> io::Result<OwnedBytes> {
panic!(
"unexpected async read of {:?} at {:?} (file length {})",
self.path, range, self.len,
);
}
}
impl HasLen for FailingHandle {
fn len(&self) -> usize {
self.len
}
}