use crate::value::{StorageKey, StorageKeyEncodeError, Value};
macro_rules! value_is_storage_key_encodable_from_registry {
( @args $value:expr; @entries $( ($scalar:ident, $family:expr, $value_pat:pat, is_numeric_value = $is_numeric:expr, supports_numeric_coercion = $supports_numeric_coercion:expr, supports_arithmetic = $supports_arithmetic:expr, supports_equality = $supports_equality:expr, supports_ordering = $supports_ordering:expr, is_keyable = $is_keyable:expr, is_storage_key_encodable = $is_storage_key_encodable:expr) ),* $(,)? ) => {
match $value {
$( $value_pat => $is_storage_key_encodable, )*
_ => false,
}
};
}
const fn runtime_value_kind_label(value: &Value) -> &'static str {
match value {
Value::Account(_) => "Account",
Value::Blob(_) => "Blob",
Value::Bool(_) => "Bool",
Value::Date(_) => "Date",
Value::Decimal(_) => "Decimal",
Value::Duration(_) => "Duration",
Value::Enum(_) => "Enum",
Value::Float32(_) => "Float32",
Value::Float64(_) => "Float64",
Value::Int(_) => "Int",
Value::Int128(_) => "Int128",
Value::IntBig(_) => "IntBig",
Value::List(_) => "List",
Value::Map(_) => "Map",
Value::Null => "Null",
Value::Principal(_) => "Principal",
Value::Subaccount(_) => "Subaccount",
Value::Text(_) => "Text",
Value::Timestamp(_) => "Timestamp",
Value::Uint(_) => "Uint",
Value::Uint128(_) => "Uint128",
Value::UintBig(_) => "UintBig",
Value::Ulid(_) => "Ulid",
Value::Unit => "Unit",
}
}
#[must_use]
pub(crate) const fn storage_key_as_runtime_value(key: &StorageKey) -> Value {
match key {
StorageKey::Account(v) => Value::Account(*v),
StorageKey::Int(v) => Value::Int(*v),
StorageKey::Principal(v) => Value::Principal(*v),
StorageKey::Subaccount(v) => Value::Subaccount(*v),
StorageKey::Timestamp(v) => Value::Timestamp(*v),
StorageKey::Uint(v) => Value::Uint(*v),
StorageKey::Ulid(v) => Value::Ulid(*v),
StorageKey::Unit => Value::Unit,
}
}
pub(crate) const fn storage_key_from_runtime_value(
value: &Value,
) -> Result<StorageKey, StorageKeyEncodeError> {
let is_storage_key_encodable =
scalar_registry!(value_is_storage_key_encodable_from_registry, value);
if !is_storage_key_encodable {
return Err(StorageKeyEncodeError::UnsupportedValueKind {
kind: runtime_value_kind_label(value),
});
}
match value {
Value::Account(v) => Ok(StorageKey::Account(*v)),
Value::Int(v) => Ok(StorageKey::Int(*v)),
Value::Principal(v) => Ok(StorageKey::Principal(*v)),
Value::Subaccount(v) => Ok(StorageKey::Subaccount(*v)),
Value::Timestamp(v) => Ok(StorageKey::Timestamp(*v)),
Value::Uint(v) => Ok(StorageKey::Uint(*v)),
Value::Ulid(v) => Ok(StorageKey::Ulid(*v)),
Value::Unit => Ok(StorageKey::Unit),
_ => Err(StorageKeyEncodeError::UnsupportedValueKind {
kind: runtime_value_kind_label(value),
}),
}
}