use crate::{
Mappable,
Result as StorageResult,
blueprint::{
BlueprintCodec,
BlueprintInspect,
plain::Plain,
sparse::{
PrimaryKey,
Sparse,
},
},
codec::{
postcard::Postcard,
primitive::Primitive,
raw::Raw,
},
kv_store::{
KeyValueInspect,
StorageColumn,
Value,
},
merkle::column::{
AsU32,
MerkleizedColumn,
},
structured_storage::TableWithBlueprint,
tables::merkle::SparseMerkleMetadata,
};
use alloc::borrow::Cow;
use fuel_core_types::fuel_merkle::sparse;
pub struct MerkleData<Table>(core::marker::PhantomData<Table>);
impl<Table> Mappable for MerkleData<Table> {
type Key = [u8; 32];
type OwnedKey = Self::Key;
type Value = sparse::Primitive;
type OwnedValue = Self::Value;
}
impl<Table, TC> TableWithBlueprint for MerkleData<Table>
where
Table: MerkleizedTableColumn<TableColumn = TC>,
TC: core::fmt::Debug + Copy + strum::EnumCount + AsU32,
{
type Blueprint = Plain<Raw, Postcard>;
type Column = MerkleizedColumn<TC>;
fn column() -> Self::Column {
Self::Column::MerkleDataColumn(Table::table_column())
}
}
pub struct MerkleMetadata<TC>(core::marker::PhantomData<TC>);
impl<TC> Mappable for MerkleMetadata<TC> {
type Key = u32;
type OwnedKey = Self::Key;
type Value = SparseMerkleMetadata;
type OwnedValue = Self::Value;
}
impl<TC> TableWithBlueprint for MerkleMetadata<TC>
where
TC: core::fmt::Debug + Copy + strum::EnumCount + AsU32,
{
type Blueprint = Plain<Primitive<4>, Postcard>;
type Column = MerkleizedColumn<TC>;
fn column() -> Self::Column {
Self::Column::MerkleMetadataColumn
}
}
pub struct KeyConverter<Table>(core::marker::PhantomData<Table>);
impl<Table> PrimaryKey for KeyConverter<Table>
where
Table: Mappable,
Table: TableWithBlueprint,
{
type InputKey = <Table as Mappable>::Key;
type OutputKey = u32;
fn primary_key(_: &Self::InputKey) -> Cow<'_, Self::OutputKey> {
Cow::Owned(Table::column().id())
}
}
pub struct Merkleized<Table>(core::marker::PhantomData<Table>);
pub trait MerkleizedTableColumn {
type TableColumn;
fn table_column() -> Self::TableColumn;
}
impl<Table, TC> Mappable for Merkleized<Table>
where
Table: Mappable + MerkleizedTableColumn<TableColumn = TC>,
{
type Key = <Table as Mappable>::Key;
type OwnedKey = <Table as Mappable>::OwnedKey;
type Value = <Table as Mappable>::Value;
type OwnedValue = <Table as Mappable>::OwnedValue;
}
type KeyCodec<Table> =
<<Table as TableWithBlueprint>::Blueprint as BlueprintCodec<Table>>::KeyCodec;
type ValueCodec<Table> =
<<Table as TableWithBlueprint>::Blueprint as BlueprintCodec<Table>>::ValueCodec;
impl<Table, TC> TableWithBlueprint for Merkleized<Table>
where
Table: Mappable + MerkleizedTableColumn<TableColumn = TC>,
Table: TableWithBlueprint,
TC: core::fmt::Debug + Copy + strum::EnumCount + AsU32,
Table::Blueprint: BlueprintInspect<Table, DummyStorage<MerkleizedColumn<TC>>>,
{
type Blueprint = Sparse<
KeyCodec<Table>,
ValueCodec<Table>,
MerkleMetadata<TC>,
MerkleData<Table>,
KeyConverter<Table>,
>;
type Column = MerkleizedColumn<TC>;
fn column() -> Self::Column {
Self::Column::TableColumn(Table::table_column())
}
}
#[derive(Default)]
pub struct DummyStorage<Column>(core::marker::PhantomData<Column>);
impl<Column> DummyStorage<Column> {
pub fn new() -> Self {
Self(core::marker::PhantomData)
}
}
impl<Column> KeyValueInspect for DummyStorage<Column>
where
Column: StorageColumn,
{
type Column = Column;
fn get(&self, _: &[u8], _: Self::Column) -> StorageResult<Option<Value>> {
unreachable!()
}
}