diff --git a/framework/base/src/lib.rs b/framework/base/src/lib.rs index 0dcde3ebea..73d5a5e0e4 100644 --- a/framework/base/src/lib.rs +++ b/framework/base/src/lib.rs @@ -34,6 +34,7 @@ pub mod types; #[cfg(feature = "std")] mod std_impl; +mod storage_v2; pub use hex_call_data::*; pub use hex_literal; diff --git a/framework/base/src/storage/storage_key.rs b/framework/base/src/storage/storage_key.rs index 74b4fa5171..99fa1f4eea 100644 --- a/framework/base/src/storage/storage_key.rs +++ b/framework/base/src/storage/storage_key.rs @@ -8,6 +8,7 @@ use crate::{ *, }; +#[derive(Default)] pub struct StorageKey where A: ManagedTypeApi + ErrorApi + 'static, @@ -116,3 +117,12 @@ impl Clone for StorageKey { } } } + +impl PartialEq for StorageKey +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + fn eq(&self, other: &Self) -> bool { + self.buffer.eq(&other.buffer) + } +} diff --git a/framework/base/src/storage_v2.rs b/framework/base/src/storage_v2.rs new file mode 100644 index 0000000000..6953eaa4f5 --- /dev/null +++ b/framework/base/src/storage_v2.rs @@ -0,0 +1,7 @@ +mod context; +mod key; + +#[allow(unused_imports)] +pub use context::*; +#[allow(unused_imports)] +pub use key::*; diff --git a/framework/base/src/storage_v2/context.rs b/framework/base/src/storage_v2/context.rs new file mode 100644 index 0000000000..427a66f979 --- /dev/null +++ b/framework/base/src/storage_v2/context.rs @@ -0,0 +1,264 @@ +use core::marker::PhantomData; + +use crate::{ + api::{ + ErrorApi, ManagedTypeApi, StorageReadApi, StorageReadApiImpl, StorageWriteApi, + StorageWriteApiImpl as _, + }, + storage::StorageKey, + types::{ManagedBuffer, ManagedType}, +}; + +#[allow(dead_code)] +pub trait StorageContext +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + type ReadAccess: StorageContextRead; + type WriteAccess: StorageContextWrite; + + unsafe fn unsafe_clone(&self) -> Self; + + fn downcast_read(&self) -> &Self::ReadAccess; + + fn try_downcast_write(&self) -> Option<&Self::WriteAccess>; + + fn subcontext(&self, delta: StorageKey) -> Self; +} + +#[allow(dead_code)] +pub trait StorageContextRead: StorageContext +where + R: ManagedTypeApi + ErrorApi + 'static, +{ + fn read_raw(&self) -> StorageKey; +} + +#[allow(dead_code)] +pub trait StorageContextWrite: StorageContextRead +where + W: ManagedTypeApi + ErrorApi + 'static, +{ + fn write_raw(&self, value: ManagedBuffer); +} + +/// Layout marker. +/// +/// Cannot create instance of this type. +#[allow(dead_code)] +pub enum Layout {} + +impl StorageContext for Layout +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + type ReadAccess = NoAccess; + type WriteAccess = NoAccess; + + unsafe fn unsafe_clone(&self) -> Self { + unreachable!() + } + + fn downcast_read(&self) -> &Self::ReadAccess { + unreachable!() + } + + fn try_downcast_write(&self) -> Option<&Self::WriteAccess> { + unreachable!() + } + + fn subcontext(&self, _delta: StorageKey) -> Self { + unreachable!() + } +} + +pub enum NoAccess +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + _Phantom(PhantomData), +} + +impl StorageContext for NoAccess +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + type ReadAccess = NoAccess; + type WriteAccess = NoAccess; + + unsafe fn unsafe_clone(&self) -> Self { + unreachable!() + } + + fn downcast_read(&self) -> &Self::ReadAccess { + unreachable!() + } + + fn try_downcast_write(&self) -> Option<&Self::WriteAccess> { + unreachable!() + } + + fn subcontext(&self, _delta: StorageKey) -> Self { + unreachable!() + } +} + +impl StorageContextRead for NoAccess +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + fn read_raw(&self) -> StorageKey { + unreachable!() + } +} + +impl StorageContextWrite for NoAccess +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + fn write_raw(&self, _value: ManagedBuffer) { + unreachable!() + } +} + +#[allow(dead_code)] +#[derive(Default)] +pub struct SelfRead<'r, M> +where + M: ManagedTypeApi + ErrorApi + 'static, +{ + key: StorageKey, + _phantom: PhantomData<&'r ()>, +} + +#[allow(dead_code)] +impl SelfRead<'_, M> +where + M: ManagedTypeApi + ErrorApi + 'static, +{ + pub fn new(key: StorageKey) -> Self { + SelfRead { + key, + _phantom: PhantomData, + } + } +} + +impl StorageContext for SelfRead<'_, A> +where + A: StorageReadApi + ManagedTypeApi + ErrorApi + 'static, +{ + type ReadAccess = Self; + type WriteAccess = NoAccess; + + unsafe fn unsafe_clone(&self) -> Self { + Self { + key: self.key.clone(), + _phantom: PhantomData, + } + } + + fn downcast_read(&self) -> &Self::ReadAccess { + self + } + + fn try_downcast_write(&self) -> Option<&Self::WriteAccess> { + None + } + + fn subcontext(&self, delta: StorageKey) -> Self { + let mut subcontext_key = self.key.clone(); + subcontext_key.append_managed_buffer(&delta.buffer); + Self::new(subcontext_key) + } +} + +impl StorageContextRead for SelfRead<'_, A> +where + A: StorageReadApi + ManagedTypeApi + ErrorApi + 'static, +{ + fn read_raw(&self) -> StorageKey { + unsafe { + let result = ManagedBuffer::new_uninit(); + A::storage_read_api_impl() + .storage_load_managed_buffer_raw(self.key.get_handle(), result.get_handle()); + StorageKey::from(result) + } + } +} + +#[allow(dead_code)] +#[derive(Default)] +pub struct SelfWrite<'w, M> +where + M: ManagedTypeApi + ErrorApi + 'static, +{ + key: StorageKey, + _phantom: PhantomData<&'w mut ()>, +} + +#[allow(dead_code)] +impl SelfWrite<'_, M> +where + M: ManagedTypeApi + ErrorApi + 'static, +{ + pub fn new(key: StorageKey) -> Self { + SelfWrite { + key, + _phantom: PhantomData, + } + } +} + +impl StorageContext for SelfWrite<'_, A> +where + A: StorageReadApi + StorageWriteApi + ManagedTypeApi + ErrorApi + 'static, +{ + type ReadAccess = Self; + type WriteAccess = Self; + + unsafe fn unsafe_clone(&self) -> Self { + Self { + key: self.key.clone(), + _phantom: PhantomData, + } + } + + fn downcast_read(&self) -> &Self::ReadAccess { + self + } + + fn try_downcast_write(&self) -> Option<&Self::WriteAccess> { + Some(self) + } + + fn subcontext(&self, delta: StorageKey) -> Self { + let mut subcontext_key = self.key.clone(); + subcontext_key.append_managed_buffer(&delta.buffer); + Self::new(subcontext_key) + } +} + +impl StorageContextRead for SelfWrite<'_, A> +where + A: StorageWriteApi + StorageReadApi + ManagedTypeApi + ErrorApi + 'static, +{ + fn read_raw(&self) -> StorageKey { + unsafe { + let result = ManagedBuffer::new_uninit(); + A::storage_read_api_impl() + .storage_load_managed_buffer_raw(self.key.get_handle(), result.get_handle()); + StorageKey::from(result) + } + } +} + +impl StorageContextWrite for SelfWrite<'_, A> +where + A: StorageReadApi + StorageWriteApi + ManagedTypeApi + ErrorApi + 'static, +{ + fn write_raw(&self, value: ManagedBuffer) { + A::storage_write_api_impl() + .storage_store_managed_buffer_raw(self.key.get_handle(), value.handle.clone()); + } +} diff --git a/framework/base/src/storage_v2/key.rs b/framework/base/src/storage_v2/key.rs new file mode 100644 index 0000000000..e07f5b7c8c --- /dev/null +++ b/framework/base/src/storage_v2/key.rs @@ -0,0 +1,376 @@ +use core::{ + marker::PhantomData, + ops::{Deref, DerefMut}, + ptr::NonNull, +}; + +use alloc::borrow::ToOwned; + +use crate::{ + api::{ + ErrorApi, ManagedTypeApi, StorageReadApi, StorageReadApiImpl, StorageWriteApi, + StorageWriteApiImpl, + }, + storage::StorageKey, + types::{ManagedBuffer, ManagedType}, +}; + +#[allow(dead_code)] +pub trait Key: 'static +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + fn full_key(&self) -> StorageKey; + + fn key_eq>(&self, other: &Other) -> bool { + self.full_key().eq(&other.full_key()) + } + + fn append_to(&self, target: &mut StorageKey) { + target.append_bytes(b"."); + target.append_managed_buffer(&self.full_key().buffer); + } +} + +impl Key for StorageKey +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + fn full_key(&self) -> StorageKey { + self.clone() + } +} + +#[allow(dead_code)] +pub trait ConstKey: Key + Default +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + fn root_key() -> &'static ManagedBuffer; +} + +// impl Key for K +// where +// K: ConstKey, +// A: ManagedTypeApi + ErrorApi + 'static, +// { +// fn full_key(&self) -> DynamicKey { +// K::root_key().to_owned() +// } + +// fn key_eq>(&self, other: &Other) -> bool { +// false +// // TypeId::of::() == TypeId::of::() +// } +// } + +#[allow(dead_code)] +pub struct StrKey(&'static str); + +impl Deref for StrKey { + type Target = &'static str; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Key for StrKey +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + fn full_key(&self) -> StorageKey { + StorageKey::new(self.as_bytes()) + } +} + +#[allow(dead_code)] +pub trait StoragePath: Sized +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + fn read_value_raw(&self) -> StorageKey; + + fn maybe_write_value_raw(&mut self, value: &ManagedBuffer); + + unsafe fn duplicate_unchecked(&self) -> Self; + + fn concat_key>(self, key: K) -> Self; + + // fn concat_key_ref(&self, key: K) -> Self { + // unsafe { self.duplicate_unchecked().concat_key(key) } + // } + + // fn concat_key_ref_mut(&mut self, key: K) -> Self { + // unsafe { self.duplicate_unchecked().concat_key(key) } + // } +} + +#[allow(dead_code)] +pub trait StoragePathMut: StoragePath +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + fn write_value_raw(&mut self, value: &ManagedBuffer); +} + +#[allow(dead_code)] +pub trait StoragePathIntoRefMut<'a, A>: StoragePathMut +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + type RefMut: StoragePathMut; + + fn as_ref_mut(&'a mut self) -> Self::RefMut; +} + +#[allow(dead_code)] +pub trait StoragePathConcat +where + K: Key, + A: ManagedTypeApi + ErrorApi + 'static, +{ + type Output: StoragePath; + + fn concat(self, key: K) -> Self::Output; +} + +// pub trait StoragePathMut { +// fn write_value_raw(&self, value: &str); + +// unsafe fn duplicate_unchecked_mut(&self) -> Self; +// } + +#[derive(Default)] +pub struct SelfStorageRoot; + +#[allow(dead_code)] +#[derive(Default)] +pub struct SelfStorageRootMut; + +#[allow(dead_code)] +pub struct SelfStorageRootRef<'a, A> { + _phantom: PhantomData<(&'a SelfStorageRoot, A)>, +} + +#[allow(dead_code)] +impl<'a, A> SelfStorageRootRef<'a, A> +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + pub unsafe fn new_ref() -> Self { + SelfStorageRootRef { + _phantom: PhantomData, + } + } + + pub fn root_path(self, root_key: &StorageKey) -> SelfStorageRef<'a, A> { + SelfStorageRef { + source_ref: self, + key: root_key.to_owned(), + } + } +} + +// impl<'a> Deref for SelfStorageRootRef<'a> { +// type Target = SelfStorageRoot; + +// // fn deref(&self) -> &Self::Target { +// // &SelfStorageRoot +// // } +// } + +pub struct SelfStorageRootRefMut<'a, A> { + _phantom: PhantomData<(&'a SelfStorageRoot, A)>, +} + +#[allow(dead_code)] +impl<'a, A> SelfStorageRootRefMut<'a, A> +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + pub unsafe fn new_ref() -> Self { + SelfStorageRootRefMut { + _phantom: PhantomData, + } + } + + pub fn root_path(self, root_key: &StorageKey) -> SelfStorageRefMut<'a, A> { + SelfStorageRefMut { + source_ref: self, + key: root_key.to_owned(), + } + } +} + +impl<'a, _A> Deref for SelfStorageRootRefMut<'a, _A> { + type Target = SelfStorageRoot; + + fn deref(&self) -> &Self::Target { + &SelfStorageRoot + } +} + +impl<'a, _A> DerefMut for SelfStorageRootRefMut<'a, _A> { + fn deref_mut(&mut self) -> &mut Self::Target { + let ptr = NonNull::::dangling(); + unsafe { &mut *ptr.as_ptr() } + } +} + +#[allow(dead_code)] +pub struct SelfStorageRef<'a, A> +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + pub source_ref: SelfStorageRootRef<'a, A>, + pub key: StorageKey, +} + +impl<'a, A> StoragePath for SelfStorageRef<'a, A> +where + A: StorageWriteApi + StorageReadApi + ManagedTypeApi + ErrorApi + 'static, +{ + fn read_value_raw(&self) -> StorageKey { + unsafe { + let result = ManagedBuffer::new_uninit(); + A::storage_read_api_impl() + .storage_load_managed_buffer_raw(self.key.get_handle(), result.get_handle()); + StorageKey::from(result) + } + } + + fn maybe_write_value_raw(&mut self, value: &ManagedBuffer) { + // read-only + let storage_path = self.key.clone(); + A::storage_write_api_impl() + .storage_store_managed_buffer_raw(storage_path.get_handle(), value.get_handle()); + } + + unsafe fn duplicate_unchecked(&self) -> Self { + SelfStorageRef { + source_ref: SelfStorageRootRef::new_ref(), + key: self.key.clone(), + } + } + + fn concat_key>(mut self, key: K) -> Self { + key.append_to(&mut self.key); + self + } +} + +// impl<'a, K: Key> StoragePathConcat for SelfStorageRootRef<'a> { +// type Output = SelfStorageRef<'a>; + +// fn concat(self, key: K) -> Self::Output { +// SelfStorageRef { +// source_ref: self, +// key: key.full_key(), +// } +// } +// } + +#[allow(dead_code)] +pub struct SelfStorageRefMut<'a, A> +where + A: ManagedTypeApi + ErrorApi + 'static, +{ + pub source_ref: SelfStorageRootRefMut<'a, A>, + pub key: StorageKey, +} + +impl<'a, A> StoragePath for SelfStorageRefMut<'a, A> +where + A: StorageReadApi + StorageWriteApi + ManagedTypeApi + ErrorApi + 'static, +{ + fn read_value_raw(&self) -> StorageKey { + unsafe { + let result = ManagedBuffer::new_uninit(); + A::storage_read_api_impl() + .storage_load_managed_buffer_raw(self.key.get_handle(), result.get_handle()); + StorageKey::from(result) + } + } + + fn maybe_write_value_raw(&mut self, value: &ManagedBuffer) { + A::storage_write_api_impl() + .storage_store_managed_buffer_raw(self.key.get_handle(), value.get_handle()); + } + + unsafe fn duplicate_unchecked(&self) -> Self { + SelfStorageRefMut { + source_ref: SelfStorageRootRefMut::new_ref(), + key: self.key.clone(), + } + } + + fn concat_key>(mut self, key: K) -> Self { + key.append_to(&mut self.key); + self + } +} + +impl<'a, A> StoragePathMut for SelfStorageRefMut<'a, A> +where + A: StorageWriteApi + StorageReadApi + ManagedTypeApi + ErrorApi + 'static, +{ + fn write_value_raw(&mut self, value: &ManagedBuffer) { + A::storage_write_api_impl() + .storage_store_managed_buffer_raw(self.key.get_handle(), value.get_handle()); + } +} + +impl<'a, A> StoragePathIntoRefMut<'a, A> for SelfStorageRefMut<'a, A> +where + A: StorageWriteApi + StorageReadApi + ManagedTypeApi + ErrorApi + 'static, +{ + type RefMut = SelfStorageRefMut<'a, A>; + + fn as_ref_mut(&'a mut self) -> Self::RefMut { + unsafe { self.duplicate_unchecked() } + } +} + +impl<'a, A, K> StoragePathConcat for SelfStorageRootRefMut<'a, A> +where + K: Key, + A: StorageWriteApi + StorageReadApi + ManagedTypeApi + ErrorApi + 'static, +{ + type Output = SelfStorageRefMut<'a, A>; + + fn concat(self, key: K) -> Self::Output { + SelfStorageRefMut { + source_ref: self, + key: key.full_key(), + } + } +} + +#[allow(dead_code)] +pub trait StorageSource: Default + 'static { + fn can_write() -> bool; +} + +impl StorageSource for SelfStorageRoot { + fn can_write() -> bool { + // println!("SelfStorage false"); + false + } +} +impl StorageSource for SelfStorageRootMut { + fn can_write() -> bool { + // println!("SelfStorageMut true"); + true + } +} + +pub fn _path_lifetimes(root: SelfStorageRootRefMut<'_, A>) +where + A: StorageWriteApi + StorageReadApi + ManagedTypeApi + ErrorApi + 'static, +{ + let mut path1 = root.root_path(&StorageKey::new(b"root")); + let _path1a = path1.as_ref_mut().concat_key(StrKey("key1a")); + // let path1b = path1.into_ref_mut().concat_key("key1a".to_owned()); + // let path1a = path1.concat_key("key1a".to_owned()); +}