use std::{future::Future, pin::Pin};
use thiserror::Error;
pub type BoxFuture<T> = Pin<Box<dyn Future<Output = T> + Send + 'static>>;
#[derive(Error, Debug)]
pub enum RandomAccessError {
#[error("{} out of bounds. {} < {}{}",
.end.as_ref().map_or_else(|| "Offset", |_| "Range"),
.length,
.offset,
.end.as_ref().map_or_else(String::new, |end| format!("..{}", end)))]
OutOfBounds {
offset: u64,
end: Option<u64>,
length: u64,
},
#[error("Unrecoverable input/output error occured.{}{}",
.return_code.as_ref().map_or_else(String::new, |rc| format!(" Return code: {}.", rc)),
.context.as_ref().map_or_else(String::new, |ctx| format!(" Context: {}.", ctx)))]
IO {
return_code: Option<i32>,
context: Option<String>,
#[source]
source: std::io::Error,
},
}
impl From<std::io::Error> for RandomAccessError {
fn from(err: std::io::Error) -> Self {
Self::IO {
return_code: None,
context: None,
source: err,
}
}
}
pub trait RandomAccess {
fn write(&self, offset: u64, data: &[u8]) -> BoxFuture<Result<(), RandomAccessError>>;
fn read(&self, offset: u64, length: u64) -> BoxFuture<Result<Vec<u8>, RandomAccessError>>;
fn del(&self, offset: u64, length: u64) -> BoxFuture<Result<(), RandomAccessError>>;
fn truncate(&self, length: u64) -> BoxFuture<Result<(), RandomAccessError>>;
fn len(&self) -> u64;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn sync_all(&self) -> BoxFuture<Result<(), RandomAccessError>> {
Box::pin(std::future::ready(Ok(())))
}
}