dharitri_sc/storage/
storage_get.rs1use core::{convert::Infallible, marker::PhantomData};
2
3use crate::{
4 api::{
5 const_handles, use_raw_handle, ErrorApi, ErrorApiImpl, HandleConstraints,
6 ManagedBufferApiImpl, ManagedTypeApi, StorageReadApi, StorageReadApiImpl,
7 },
8 codec::*,
9 err_msg,
10 types::{
11 BigInt, BigUint, ManagedBuffer, ManagedBufferNestedDecodeInput, ManagedRef, ManagedType,
12 },
13};
14use alloc::boxed::Box;
15use unwrap_infallible::UnwrapInfallible;
16
17use super::StorageKey;
18
19struct StorageGetInput<'k, A>
20where
21 A: StorageReadApi + ManagedTypeApi + ErrorApi + 'static,
22{
23 key: ManagedRef<'k, A, StorageKey<A>>,
24}
25
26impl<'k, A> StorageGetInput<'k, A>
27where
28 A: StorageReadApi + ManagedTypeApi + ErrorApi + 'static,
29{
30 #[inline]
31 fn new(key: ManagedRef<'k, A, StorageKey<A>>) -> Self {
32 StorageGetInput { key }
33 }
34
35 fn to_managed_buffer(&self) -> ManagedBuffer<A> {
36 unsafe {
37 let result = ManagedBuffer::new_uninit();
38 A::storage_read_api_impl()
39 .storage_load_managed_buffer_raw(self.key.buffer.get_handle(), result.get_handle());
40 result
41 }
42 }
43
44 fn to_big_uint(&self) -> BigUint<A> {
45 BigUint::from_bytes_be_buffer(&self.to_managed_buffer())
46 }
47
48 fn to_big_int(&self) -> BigInt<A> {
49 BigInt::from_signed_bytes_be_buffer(&self.to_managed_buffer())
50 }
51
52 fn load_len_managed_buffer(&self) -> usize {
53 let value_handle: A::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1);
54 A::storage_read_api_impl()
55 .storage_load_managed_buffer_raw(self.key.buffer.get_handle(), value_handle.clone());
56 A::managed_type_impl().mb_len(value_handle)
57 }
58}
59
60impl<A> TopDecodeInput for StorageGetInput<'_, A>
61where
62 A: StorageReadApi + ManagedTypeApi + ErrorApi + 'static,
63{
64 type NestedBuffer = ManagedBufferNestedDecodeInput<A>;
65
66 fn byte_len(&self) -> usize {
67 self.load_len_managed_buffer()
68 }
69
70 fn into_boxed_slice_u8(self) -> Box<[u8]> {
71 self.to_managed_buffer().to_boxed_bytes().into_box()
72 }
73
74 #[inline]
75 fn into_max_size_buffer<H, const MAX_LEN: usize>(
76 self,
77 buffer: &mut [u8; MAX_LEN],
78 h: H,
79 ) -> Result<&[u8], H::HandledErr>
80 where
81 H: DecodeErrorHandler,
82 {
83 self.to_managed_buffer().into_max_size_buffer(buffer, h)
84 }
85
86 #[inline]
87 fn into_max_size_buffer_align_right<H, const MAX_LEN: usize>(
88 self,
89 buffer: &mut [u8; MAX_LEN],
90 h: H,
91 ) -> Result<usize, H::HandledErr>
92 where
93 H: DecodeErrorHandler,
94 {
95 self.to_managed_buffer()
96 .into_max_size_buffer_align_right(buffer, h)
97 }
98
99 #[inline]
100 fn into_i64<H>(self, h: H) -> Result<i64, H::HandledErr>
101 where
102 H: DecodeErrorHandler,
103 {
104 self.to_managed_buffer().into_i64(h)
105 }
106
107 #[inline]
108 fn supports_specialized_type<T: TryStaticCast>() -> bool {
109 T::type_eq::<ManagedBuffer<A>>() || T::type_eq::<BigUint<A>>() || T::type_eq::<BigInt<A>>()
110 }
111
112 #[inline]
113 fn into_specialized<T, H>(self, h: H) -> Result<T, H::HandledErr>
114 where
115 T: TryStaticCast,
116 H: DecodeErrorHandler,
117 {
118 if let Some(result) = try_execute_then_cast(|| self.to_managed_buffer()) {
119 Ok(result)
120 } else if let Some(result) = try_execute_then_cast(|| self.to_big_uint()) {
121 Ok(result)
122 } else if let Some(result) = try_execute_then_cast(|| self.to_big_int()) {
123 Ok(result)
124 } else {
125 Err(h.handle_error(DecodeError::UNSUPPORTED_OPERATION))
126 }
127 }
128
129 fn into_nested_buffer(self) -> Self::NestedBuffer {
130 ManagedBufferNestedDecodeInput::new(self.to_managed_buffer())
131 }
132}
133
134pub fn storage_get<A, T>(key: ManagedRef<'_, A, StorageKey<A>>) -> T
135where
136 T: TopDecode,
137 A: StorageReadApi + ManagedTypeApi + ErrorApi,
138{
139 let handle = key.get_handle().get_raw_handle_unchecked();
140 T::top_decode_or_handle_err(
141 StorageGetInput::new(key),
142 StorageGetErrorHandler::<A>::new(handle),
143 )
144 .unwrap_infallible()
145}
146
147pub fn storage_get_len<A>(key: ManagedRef<'_, A, StorageKey<A>>) -> usize
150where
151 A: StorageReadApi + ManagedTypeApi + ErrorApi,
152{
153 let input = StorageGetInput::new(key);
154 input.load_len_managed_buffer()
155}
156
157#[derive(Clone)]
161pub(crate) struct StorageGetErrorHandler<M>
162where
163 M: ManagedTypeApi + ErrorApi,
164{
165 _phantom: PhantomData<M>,
166 key: i32,
167}
168
169impl<M> Copy for StorageGetErrorHandler<M> where M: ManagedTypeApi + ErrorApi {}
170
171impl<M> StorageGetErrorHandler<M>
172where
173 M: ManagedTypeApi + ErrorApi,
174{
175 #[inline]
176 pub fn new(key: i32) -> Self {
177 StorageGetErrorHandler {
178 _phantom: PhantomData,
179 key,
180 }
181 }
182}
183
184impl<M> DecodeErrorHandler for StorageGetErrorHandler<M>
185where
186 M: ManagedTypeApi + ErrorApi,
187{
188 type HandledErr = Infallible;
189
190 fn handle_error(&self, err: DecodeError) -> Self::HandledErr {
191 let mut message_buffer =
192 ManagedBuffer::<M>::new_from_bytes(err_msg::STORAGE_DECODE_ERROR_1.as_bytes());
193 M::managed_type_impl().mb_append(message_buffer.get_handle(), self.key.into());
194 message_buffer.append_bytes(err_msg::STORAGE_DECODE_ERROR_2.as_bytes());
195 message_buffer.append_bytes(err.message_bytes());
196 M::error_api_impl().signal_error_from_buffer(message_buffer.get_handle())
197 }
198}