Skip to content

Commit

Permalink
slice structured values
Browse files Browse the repository at this point in the history
  • Loading branch information
miraclx committed Jun 26, 2024
1 parent a4def77 commit b7e34a1
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 42 deletions.
8 changes: 4 additions & 4 deletions crates/store/src/entry.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use crate::key::AsKeyParts;
use crate::slice::Slice;

pub trait DataType: Sized {
pub trait DataType<'a>: Sized {
type Error;

fn from_slice(slice: Slice) -> Result<Self, Self::Error>;
fn as_slice(&self) -> Result<Slice, Self::Error>;
fn from_slice(slice: Slice<'a>) -> Result<Self, Self::Error>;
fn as_slice(&'a self) -> Result<Slice<'a>, Self::Error>;
}

pub trait Entry {
type Key: AsKeyParts;
type DataType: DataType;
type DataType<'a>: DataType<'a>;

fn key(&self) -> &Self::Key;
}
23 changes: 13 additions & 10 deletions crates/store/src/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,26 @@ impl<'base, 'k, 'v, L: WriteLayer<'k, 'v>> StoreHandle<L> {
}

#[derive(Debug, Error)]
pub enum Error<E: DataType> {
pub enum Error<'a, E: DataType<'a>> {
LayerError(eyre::Report),
CodecError(E::Error),
}

impl<E: DataType> From<eyre::Report> for Error<E> {
impl<'a, E: DataType<'a>> From<eyre::Report> for Error<'a, E> {
fn from(err: eyre::Report) -> Self {
Self::LayerError(err)
}
}

impl<'k, L: ReadLayer<'k>> StoreHandle<L> {
pub fn has<E: Entry>(&self, entry: &'k E) -> Result<bool, Error<E::DataType>> {
impl<'a, 'k, L: ReadLayer<'k>> StoreHandle<L> {
pub fn has<E: Entry>(&self, entry: &'k E) -> Result<bool, Error<E::DataType<'_>>> {
Ok(self.inner.has(entry.key())?)
}

pub fn get<E: Entry>(&self, entry: &'k E) -> Result<Option<E::DataType>, Error<E::DataType>> {
pub fn get<E: Entry>(
&self,
entry: &'k E,
) -> Result<Option<E::DataType<'_>>, Error<E::DataType<'_>>> {
match self.inner.get(entry.key())? {
Some(value) => Ok(Some(
E::DataType::from_slice(value).map_err(Error::CodecError)?,
Expand All @@ -61,23 +64,23 @@ impl<'k, L: ReadLayer<'k>> StoreHandle<L> {
pub fn iter<E: Entry<Key: FromKeyParts>>(
&'k self,
start: &'k E,
) -> Result<Iter<Structured<E::Key>, Structured<E::DataType>>, Error<E::DataType>> {
) -> Result<Iter<Structured<E::Key>, Structured<E::DataType<'_>>>, Error<E::DataType<'_>>> {
Ok(self.inner.iter(start.key())?.structured_value())
}
}

impl<'k, 'v, L: WriteLayer<'k, 'v>> StoreHandle<L> {
pub fn put<E: Entry>(
&mut self,
&'v mut self,
entry: &'k E,
value: &'v E::DataType,
) -> Result<(), Error<E::DataType>> {
value: &'v E::DataType<'v>,
) -> Result<(), Error<E::DataType<'_>>> {
self.inner
.put(entry.key(), value.as_slice().map_err(Error::CodecError)?)
.map_err(Error::LayerError)
}

pub fn delete<E: Entry>(&mut self, entry: &'k E) -> Result<(), Error<E::DataType>> {
pub fn delete<E: Entry>(&mut self, entry: &'k E) -> Result<(), Error<E::DataType<'_>>> {
self.inner.delete(entry.key()).map_err(Error::LayerError)
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/store/src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl<'a, V> Iter<'a, Unstructured, V> {
}

impl<'a, K> Iter<'a, K, Unstructured> {
pub fn structured_value<V: DataType>(self) -> Iter<'a, K, Structured<V>> {
pub fn structured_value<V: DataType<'a>>(self) -> Iter<'a, K, Structured<V>> {
Iter {
inner: self.inner,
_priv: PhantomData,
Expand Down Expand Up @@ -158,7 +158,7 @@ impl<'a, K: FromKeyParts> TryIntoKey<'a> for Structured<K> {
}
}

impl<'a, V: DataType> TryIntoValue<'a> for Structured<V> {
impl<'a, V: DataType<'a>> TryIntoValue<'a> for Structured<V> {
type Value = V;
type Error = Error<V::Error>;

Expand Down
4 changes: 2 additions & 2 deletions crates/store/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ pub use context::{ContextIdentity, ContextMeta, ContextState, ContextTransaction
pub use generic::GenericData;

pub trait PredefinedEntry: key::AsKeyParts {
type DataType: DataType;
type DataType<'a>: DataType<'a>;
}

impl<T: PredefinedEntry> Entry for T {
type Key = T;
type DataType = T::DataType;
type DataType<'a> = T::DataType<'a>;

fn key(&self) -> &Self::Key {
self
Expand Down
46 changes: 29 additions & 17 deletions crates/store/src/types/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ use crate::slice::Slice;
use crate::types::PredefinedEntry;

#[derive(Eq, Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize)]
pub struct ContextMeta {}
pub struct ContextMeta {
// todo! make [u8; 32] when application_id<->meta is a separate record
pub application_id: Box<str>,
}

impl DataType for ContextMeta {
impl DataType<'_> for ContextMeta {
type Error = io::Error;

fn from_slice(slice: Slice) -> Result<Self, Self::Error> {
Expand All @@ -23,32 +26,36 @@ impl DataType for ContextMeta {
}

impl PredefinedEntry for key::ContextMeta {
type DataType = ContextMeta;
type DataType<'a> = ContextMeta;
}

#[derive(Eq, Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize)]
pub struct ContextState {}
#[derive(Eq, Clone, Debug, PartialEq)]
pub struct ContextState<'a> {
pub value: Slice<'a>,
}

impl DataType for ContextState {
impl<'a> DataType<'a> for ContextState<'a> {
type Error = io::Error;

fn from_slice(slice: Slice) -> Result<Self, Self::Error> {
borsh::from_slice(&slice)
fn from_slice(slice: Slice<'a>) -> Result<Self, Self::Error> {
Ok(Self { value: slice })
}

fn as_slice(&self) -> Result<Slice, Self::Error> {
borsh::to_vec(self).map(Into::into)
fn as_slice(&'a self) -> Result<Slice<'a>, Self::Error> {
Ok(self.value.as_ref().into())
}
}

impl PredefinedEntry for key::ContextState {
type DataType = ContextState;
type DataType<'a> = ContextState<'a>;
}

#[derive(Eq, Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize)]
pub struct ContextIdentity {}
pub struct ContextIdentity {
pub private_key: Option<[u8; 32]>,
}

impl DataType for ContextIdentity {
impl DataType<'_> for ContextIdentity {
type Error = io::Error;

fn from_slice(slice: Slice) -> Result<Self, Self::Error> {
Expand All @@ -61,13 +68,18 @@ impl DataType for ContextIdentity {
}

impl PredefinedEntry for key::ContextIdentity {
type DataType = ContextIdentity;
type DataType<'a> = ContextIdentity;
}

#[derive(Eq, Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize)]
pub struct ContextTransaction {}
pub struct ContextTransaction {
pub context_id: [u8; 32],
pub method: Box<str>,
pub payload: Box<[u8]>,
pub prior_hash: [u8; 32],
}

impl DataType for ContextTransaction {
impl DataType<'_> for ContextTransaction {
type Error = io::Error;

fn from_slice(slice: Slice) -> Result<Self, Self::Error> {
Expand All @@ -80,5 +92,5 @@ impl DataType for ContextTransaction {
}

impl PredefinedEntry for key::ContextTransaction {
type DataType = ContextTransaction;
type DataType<'a> = ContextTransaction;
}
16 changes: 9 additions & 7 deletions crates/store/src/types/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@ use crate::slice::Slice;
use crate::types::PredefinedEntry;

#[derive(Eq, Clone, Debug, PartialEq)]
pub struct GenericData(Box<[u8]>);
pub struct GenericData<'a> {
value: Slice<'a>,
}

impl DataType for GenericData {
impl<'a> DataType<'a> for GenericData<'a> {
type Error = Infallible;

fn from_slice(slice: Slice) -> Result<Self, Self::Error> {
Ok(Self(slice.into_boxed()))
fn from_slice(slice: Slice<'a>) -> Result<Self, Self::Error> {
Ok(Self { value: slice })
}

fn as_slice(&self) -> Result<Slice, Self::Error> {
Ok(self.0.as_ref().into())
fn as_slice(&'a self) -> Result<Slice<'a>, Self::Error> {
Ok(self.value.as_ref().into())
}
}

impl PredefinedEntry for key::Generic {
type DataType = GenericData;
type DataType<'a> = GenericData<'a>;
}

0 comments on commit b7e34a1

Please sign in to comment.