#![no_std]
#![deny(
clippy::arithmetic_side_effects,
clippy::cast_sign_loss,
clippy::cast_possible_truncation,
clippy::cast_possible_wrap,
clippy::string_slice
)]
#![deny(unsafe_code)]
#![deny(unused_crate_dependencies)]
mod impls;
extern crate alloc;
use core::borrow::Borrow;
use alloc::{
borrow::{
Cow,
ToOwned,
},
vec::Vec,
};
pub type MerkleRoot = [u8; 32];
pub trait Mappable {
type Key: ?Sized + ToOwned;
type OwnedKey: From<<Self::Key as ToOwned>::Owned> + Borrow<Self::Key> + Clone;
type Value: ?Sized + ToOwned;
type OwnedValue: From<<Self::Value as ToOwned>::Owned> + Borrow<Self::Value> + Clone;
}
pub trait StorageInspect<Type: Mappable> {
type Error;
fn get(
&self,
key: &Type::Key,
) -> Result<Option<Cow<'_, Type::OwnedValue>>, Self::Error>;
fn contains_key(&self, key: &Type::Key) -> Result<bool, Self::Error>;
}
pub trait StorageMutate<Type: Mappable>: StorageInspect<Type> {
fn insert(
&mut self,
key: &Type::Key,
value: &Type::Value,
) -> Result<(), Self::Error> {
self.replace(key, value).map(|_| ())
}
fn replace(
&mut self,
key: &Type::Key,
value: &Type::Value,
) -> Result<Option<Type::OwnedValue>, Self::Error>;
fn remove(&mut self, key: &Type::Key) -> Result<(), Self::Error> {
self.take(key).map(|_| ())
}
fn take(&mut self, key: &Type::Key) -> Result<Option<Type::OwnedValue>, Self::Error>;
}
pub trait StorageSize<Type: Mappable>: StorageInspect<Type> {
fn size_of_value(&self, key: &Type::Key) -> Result<Option<usize>, Self::Error>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[must_use]
pub enum StorageReadError {
KeyNotFound,
OutOfBounds,
}
pub trait StorageRead<Type: Mappable>: StorageInspect<Type> + StorageSize<Type> {
fn read_exact(
&self,
key: &Type::Key,
offset: usize,
buf: &mut [u8],
) -> Result<Result<usize, StorageReadError>, Self::Error>;
fn read_zerofill(
&self,
key: &Type::Key,
offset: usize,
buf: &mut [u8],
) -> Result<Result<usize, StorageReadError>, Self::Error>;
fn read_alloc(&self, key: &Type::Key) -> Result<Option<Vec<u8>>, Self::Error>;
}
pub trait StorageWrite<Type: Mappable>: StorageMutate<Type> {
fn write_bytes(&mut self, key: &Type::Key, buf: &[u8]) -> Result<(), Self::Error>;
fn replace_bytes(
&mut self,
key: &Type::Key,
buf: &[u8],
) -> Result<Option<Vec<u8>>, Self::Error>;
fn take_bytes(&mut self, key: &Type::Key) -> Result<Option<Vec<u8>>, Self::Error>;
}
pub trait MerkleRootStorage<Key, StorageType>: StorageInspect<StorageType>
where
StorageType: Mappable,
{
fn root(&self, key: &Key) -> Result<MerkleRoot, Self::Error>;
}
pub struct StorageRef<'a, T: 'a + ?Sized, Type: Mappable>(
&'a T,
core::marker::PhantomData<Type>,
);
pub trait StorageAsRef {
#[inline(always)]
fn storage<Type>(&self) -> StorageRef<'_, Self, Type>
where
Type: Mappable,
{
self.storage_as_ref()
}
#[inline(always)]
fn storage_as_ref<Type>(&self) -> StorageRef<'_, Self, Type>
where
Type: Mappable,
{
StorageRef(self, Default::default())
}
}
impl<T> StorageAsRef for T {}
pub struct StorageMut<'a, T: 'a + ?Sized, Type: Mappable>(
&'a mut T,
core::marker::PhantomData<Type>,
);
pub trait StorageAsMut {
#[inline(always)]
fn storage<Type>(&mut self) -> StorageMut<'_, Self, Type>
where
Type: Mappable,
{
self.storage_as_mut()
}
#[inline(always)]
fn storage_as_mut<Type>(&mut self) -> StorageMut<'_, Self, Type>
where
Type: Mappable,
{
StorageMut(self, Default::default())
}
}
impl<T> StorageAsMut for T {}