Skip to main content

multiversx_sc/contract_base/wrappers/
storage_raw_wrapper.rs

1use core::marker::PhantomData;
2
3use unwrap_infallible::UnwrapInfallible;
4
5use crate::api::HandleConstraints;
6use crate::codec::{TopDecode, TopEncode};
7
8use crate::{
9    api::{ErrorApi, ManagedTypeApi, StorageReadApi, StorageReadApiImpl, StorageWriteApi},
10    storage::StorageKey,
11    storage_get,
12    storage_get::StorageGetErrorHandler,
13    storage_set,
14    types::{ManagedAddress, ManagedBuffer, ManagedType},
15};
16
17#[derive(Default)]
18pub struct StorageRawWrapper<A>
19where
20    A: StorageReadApi + ManagedTypeApi + ErrorApi,
21{
22    _phantom: PhantomData<A>,
23}
24
25impl<A> StorageRawWrapper<A>
26where
27    A: StorageReadApi + StorageWriteApi + ManagedTypeApi + ErrorApi,
28{
29    pub fn new() -> Self {
30        StorageRawWrapper {
31            _phantom: PhantomData,
32        }
33    }
34
35    /// Reads storage from the given key, and deserializes the value to the provided type.
36    ///
37    /// Use only if really necessary, storage mappers should be preferred.
38    #[inline]
39    pub fn read<K, V>(&self, storage_key: K) -> V
40    where
41        K: Into<StorageKey<A>>,
42        V: TopDecode,
43    {
44        let key: StorageKey<A> = storage_key.into();
45        storage_get(key.as_ref())
46    }
47
48    /// Reads storage from another address (usually a smart contract),
49    /// from the given key, and deserializes the value to the provided type.
50    ///
51    /// This is a synchronous call, so it only works when
52    /// both the current contract and the destination are in the same shard.
53    pub fn read_from_address<K, V>(&self, address: &ManagedAddress<A>, storage_key: K) -> V
54    where
55        K: Into<StorageKey<A>>,
56        V: TopDecode,
57    {
58        let key: StorageKey<A> = storage_key.into();
59        let result_buffer = unsafe { ManagedBuffer::<A>::new_uninit() };
60        A::storage_read_api_impl().storage_load_from_address(
61            address.get_handle(),
62            key.get_handle(),
63            result_buffer.get_handle(),
64        );
65
66        V::top_decode_or_handle_err(
67            result_buffer,
68            StorageGetErrorHandler::<A>::new(key.get_handle().get_raw_handle_unchecked()),
69        )
70        .unwrap_infallible()
71    }
72
73    /// Write a serializable value to storage under the given key
74    ///
75    /// Use only if really necessary, storage mappers should be preferred.
76    #[inline]
77    pub fn write<K, V>(&self, storage_key: K, value: &V)
78    where
79        K: Into<StorageKey<A>>,
80        V: TopEncode,
81    {
82        let key: StorageKey<A> = storage_key.into();
83        storage_set(key.as_ref(), value);
84    }
85}