mod store_ext;
#[cfg(test)]
pub(crate) mod tests;
use std::borrow::Cow;
use casper_types::bytesrepr::{self, Bytes, FromBytes, ToBytes};
pub use self::store_ext::StoreExt;
use crate::global_state::transaction_source::{Readable, Writable};
pub trait Store<K, V> {
type Error: From<bytesrepr::Error>;
type Handle;
fn handle(&self) -> Self::Handle;
#[inline]
fn deserialize_value(&self, bytes: &[u8]) -> Result<V, bytesrepr::Error>
where
V: FromBytes,
{
bytesrepr::deserialize_from_slice(bytes)
}
#[inline]
fn serialize_value(&self, value: &V) -> Result<Vec<u8>, bytesrepr::Error>
where
V: ToBytes,
{
value.to_bytes()
}
fn get<T>(&self, txn: &T, key: &K) -> Result<Option<V>, Self::Error>
where
T: Readable<Handle = Self::Handle>,
K: AsRef<[u8]>,
V: FromBytes,
Self::Error: From<T::Error>,
{
let raw = self.get_raw(txn, key)?;
match raw {
Some(bytes) => {
let value = self.deserialize_value(&bytes)?;
Ok(Some(value))
}
None => Ok(None),
}
}
fn get_raw<T>(&self, txn: &T, key: &K) -> Result<Option<Bytes>, Self::Error>
where
T: Readable<Handle = Self::Handle>,
K: AsRef<[u8]>,
Self::Error: From<T::Error>,
{
let handle = self.handle();
Ok(txn.read(handle, key.as_ref())?)
}
fn put<T>(&self, txn: &mut T, key: &K, value: &V) -> Result<(), Self::Error>
where
T: Writable<Handle = Self::Handle>,
K: AsRef<[u8]>,
V: ToBytes,
Self::Error: From<T::Error>,
{
let serialized_value = self.serialize_value(value)?;
self.put_raw(txn, key, Cow::from(serialized_value))
}
fn put_raw<T>(
&self,
txn: &mut T,
key: &K,
value_bytes: Cow<'_, [u8]>,
) -> Result<(), Self::Error>
where
T: Writable<Handle = Self::Handle>,
K: AsRef<[u8]>,
Self::Error: From<T::Error>,
{
let handle = self.handle();
txn.write(handle, key.as_ref(), &value_bytes)
.map_err(Into::into)
}
}