pub mod fs;
pub mod memory;
pub use {fs::Fs, memory::Memory};
use {
crate::Addr,
tokio::io::{self, AsyncRead, AsyncWrite},
};
pub trait Storage: StorageRead + StorageWrite {}
impl<T> Storage for T where T: StorageRead + StorageWrite {}
#[allow(clippy::module_name_repetitions)]
#[async_trait::async_trait]
pub trait StorageRead: Sync {
async fn read<A, W>(&self, addr: A, w: W) -> Result<u64, Error>
where
A: AsRef<Addr> + 'static + Send,
W: AsyncWrite + Unpin + Send;
async fn read_string<A>(&self, addr: A) -> Result<String, Error>
where
A: AsRef<Addr> + 'static + Send,
{
let mut buf = Vec::new();
self.read(addr, &mut buf).await?;
let s = std::str::from_utf8(&buf)?.to_owned();
Ok(s)
}
}
#[allow(clippy::module_name_repetitions)]
#[async_trait::async_trait]
pub trait StorageWrite: Sync {
async fn write<A, R>(&self, addr: A, r: R) -> Result<u64, Error>
where
A: AsRef<Addr> + 'static + Send,
R: AsyncRead + Unpin + Send;
async fn write_string<A>(&self, addr: A, s: String) -> Result<u64, Error>
where
A: AsRef<Addr> + 'static + Send,
{
let b = s.as_bytes();
self.write(addr, &*b).await
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("unhandled error: `{message}`")]
Unhandled { message: String },
#[error("hash `{addr}` not found")]
NotFound { addr: Addr },
#[error("io error: {0}")]
Io(#[from] io::Error),
#[error("hash `{hash}` io error: {err}")]
IoHash { hash: String, err: io::Error },
#[error("utf8 error: {0}")]
Utf8(#[from] std::str::Utf8Error),
#[error("hash `{hash}` io error: {err}")]
Utf8Hash {
hash: String,
err: std::str::Utf8Error,
},
}
impl Error {
pub fn is_not_found(&self) -> bool {
matches!(self, Self::NotFound { .. })
}
}
pub trait AsStorageRef {
type Storage: Storage;
fn as_storage_ref(&self) -> &Self::Storage;
}
#[async_trait::async_trait]
impl StorageRead for () {
async fn read<A, W>(&self, _: A, _: W) -> Result<u64, Error>
where
A: AsRef<Addr> + 'static + Send,
W: AsyncWrite + Unpin + Send,
{
Ok(0)
}
}
#[async_trait::async_trait]
impl StorageWrite for () {
async fn write<A, R>(&self, _: A, _: R) -> Result<u64, Error>
where
A: AsRef<Addr> + 'static + Send,
R: AsyncRead + Unpin + Send,
{
Ok(0)
}
}