#[macro_export]
macro_rules! single_value_storage {
($name:ident, $value_ty:ty, $key:expr, $err:expr) => {
#[odra::module]
pub struct $name;
impl $name {
pub fn set(&self, value: $value_ty) {
self.env().set_named_value($key, value);
}
pub fn get(&self) -> $value_ty {
self.env()
.get_named_value($key)
.unwrap_or_revert_with(self, $err)
}
}
};
($name:ident, $value_ty:ty, $key:expr) => {
#[odra::module]
pub struct $name;
impl $name {
pub fn set(&self, value: $value_ty) {
self.env().set_named_value($key, value);
}
pub fn get(&self) -> Option<$value_ty> {
self.env().get_named_value($key)
}
}
};
}
#[macro_export]
macro_rules! key_value_storage {
($name:ident, $dict:expr, $value_type:ty) => {
#[odra::module]
pub struct $name;
impl $name {
pub fn set(&self, key: &str, value: $value_type) {
self.env()
.set_dictionary_value($dict, key.as_bytes(), value);
}
pub fn get(&self, key: &str) -> Option<$value_type> {
self.env().get_dictionary_value($dict, key.as_bytes())
}
pub fn init(&self) {
self.env().init_dictionary($dict);
}
}
};
}
#[macro_export]
macro_rules! base64_encoded_key_value_storage {
($name:ident, $dict:expr, $key:ty, $value_type:ty) => {
#[odra::module]
pub struct $name;
impl $name {
pub fn set(&self, key: &$key, value: $value_type) {
let encoded_key = Self::key(self, key);
self.env()
.set_dictionary_value($dict, encoded_key.as_bytes(), value);
}
pub fn get(&self, key: &$key) -> Option<$value_type> {
let encoded_key = Self::key(self, key);
self.env()
.get_dictionary_value($dict, encoded_key.as_bytes())
}
pub fn init(&self) {
self.env().init_dictionary($dict);
}
#[inline]
fn key<R: odra::module::Revertible>(rev: &R, key: &$key) -> String {
use base64::prelude::{Engine, BASE64_STANDARD};
let key = odra::casper_types::bytesrepr::ToBytes::to_bytes(key);
let preimage = key.unwrap_or_revert(rev);
BASE64_STANDARD.encode(preimage)
}
}
};
}
#[macro_export]
macro_rules! compound_key_value_storage {
($name:ident, $dict:expr, $k1_type:ty, $k2_type:ty, $value_type:ty) => {
#[odra::module]
pub struct $name;
impl $name {
pub fn set(&self, key1: &$k1_type, key2: &$k2_type, value: $value_type) {
let mut key = [0u8; 64];
let mut preimage = odra::prelude::Vec::new();
let key1 = odra::casper_types::bytesrepr::ToBytes::to_bytes(key1);
let key2 = odra::casper_types::bytesrepr::ToBytes::to_bytes(key2);
preimage.extend_from_slice(&key1.unwrap_or_revert(self));
preimage.extend_from_slice(&key2.unwrap_or_revert(self));
let env = self.env();
let key_bytes = env.hash(&preimage);
odra::utils::hex_to_slice(&key_bytes, &mut key);
env.set_dictionary_value($dict, &key, value);
}
pub fn get_or_default(&self, key1: &$k1_type, key2: &$k2_type) -> $value_type {
let mut key = [0u8; 64];
let mut preimage = odra::prelude::Vec::new();
let key1 = odra::casper_types::bytesrepr::ToBytes::to_bytes(key1);
let key2 = odra::casper_types::bytesrepr::ToBytes::to_bytes(key2);
preimage.extend_from_slice(&key1.unwrap_or_revert(self));
preimage.extend_from_slice(&key2.unwrap_or_revert(self));
let env = self.env();
let key_bytes = env.hash(&preimage);
odra::utils::hex_to_slice(&key_bytes, &mut key);
env.get_dictionary_value($dict, &key).unwrap_or_default()
}
pub fn init(&self) {
self.env().init_dictionary($dict);
}
}
};
($name:ident, $dict:expr, $k1_type:ty, $value_type:ty) => {
compound_key_value_storage!($name, $dict, $k1_type, $k1_type, $value_type);
};
}