use super::*;
use crate::storage::MapStorage;
use gear_core::code::{CodeAndId, CodeMetadata, InstrumentedCode, InstrumentedCodeAndMetadata};
#[derive(Clone, Copy, Debug)]
pub enum Error {
DuplicateItem,
}
pub trait CodeStorage {
type InstrumentedCodeMap: MapStorage<Key = CodeId, Value = InstrumentedCode>;
type OriginalCodeMap: MapStorage<Key = CodeId, Value = Vec<u8>>;
type CodeMetadataMap: MapStorage<Key = CodeId, Value = CodeMetadata>;
fn reset() {
Self::CodeMetadataMap::clear();
Self::OriginalCodeMap::clear();
Self::InstrumentedCodeMap::clear();
}
fn add_code(code_and_id: CodeAndId) -> Result<(), Error> {
let (code, code_id) = code_and_id.into_parts();
let (original_code, instrumented_code, code_metadata) = code.into_parts();
Self::OriginalCodeMap::mutate(code_id, |maybe| {
if maybe.is_some() {
return Err(CodeStorageError::DuplicateItem);
}
Self::InstrumentedCodeMap::insert(code_id, instrumented_code);
Self::CodeMetadataMap::insert(code_id, code_metadata);
*maybe = Some(original_code);
Ok(())
})
}
fn update_instrumented_code_and_metadata(
code_id: CodeId,
instrumented_code_and_metadata: InstrumentedCodeAndMetadata,
) {
Self::InstrumentedCodeMap::insert(
code_id,
instrumented_code_and_metadata.instrumented_code,
);
Self::CodeMetadataMap::insert(code_id, instrumented_code_and_metadata.metadata);
}
fn update_code_metadata(code_id: CodeId, metadata: CodeMetadata) {
Self::CodeMetadataMap::insert(code_id, metadata);
}
fn original_code_exists(code_id: CodeId) -> bool {
Self::OriginalCodeMap::contains_key(&code_id)
}
fn instrumented_code_exists(code_id: CodeId) -> bool {
Self::InstrumentedCodeMap::contains_key(&code_id)
}
fn remove_code(code_id: CodeId) -> bool {
Self::OriginalCodeMap::mutate(code_id, |maybe| {
if maybe.is_none() {
return false;
}
Self::InstrumentedCodeMap::remove(code_id);
Self::CodeMetadataMap::remove(code_id);
*maybe = None;
true
})
}
fn get_instrumented_code(code_id: CodeId) -> Option<InstrumentedCode> {
Self::InstrumentedCodeMap::get(&code_id)
}
fn get_original_code(code_id: CodeId) -> Option<Vec<u8>> {
Self::OriginalCodeMap::get(&code_id)
}
fn get_code_metadata(code_id: CodeId) -> Option<CodeMetadata> {
Self::CodeMetadataMap::get(&code_id)
}
}