multiversx_sc/io/
arg_de_input.rs1use core::marker::PhantomData;
2
3use crate::{
4 api::{EndpointArgumentApi, EndpointArgumentApiImpl, ManagedTypeApi},
5 codec::{
6 try_execute_then_cast, DecodeError, DecodeErrorHandler, TopDecodeInput, TryStaticCast,
7 },
8 types::{
9 heap::Box, BigInt, BigUint, ManagedBuffer, ManagedBufferNestedDecodeInput, ManagedType,
10 },
11};
12
13pub struct ArgDecodeInput<AA>
23where
24 AA: ManagedTypeApi + EndpointArgumentApi,
25{
26 _phantom: PhantomData<AA>,
27 arg_index: i32,
28}
29
30impl<AA> ArgDecodeInput<AA>
31where
32 AA: ManagedTypeApi + EndpointArgumentApi,
33{
34 #[inline]
35 pub fn new(arg_index: i32) -> Self {
36 ArgDecodeInput {
37 _phantom: PhantomData,
38 arg_index,
39 }
40 }
41
42 fn to_managed_buffer(&self) -> ManagedBuffer<AA> {
43 unsafe {
44 let result = ManagedBuffer::new_uninit();
45 AA::argument_api_impl()
46 .load_argument_managed_buffer(self.arg_index, result.get_handle());
47 result
48 }
49 }
50
51 fn to_big_int(&self) -> BigInt<AA> {
52 unsafe {
53 let result = BigInt::new_uninit();
54 AA::argument_api_impl()
55 .load_argument_big_int_signed(self.arg_index, result.get_handle());
56 result
57 }
58 }
59
60 fn to_big_uint(&self) -> BigUint<AA> {
61 unsafe {
62 let result = BigUint::new_uninit();
63 AA::argument_api_impl()
64 .load_argument_big_int_unsigned(self.arg_index, result.get_handle());
65 result
66 }
67 }
68}
69
70impl<AA> TopDecodeInput for ArgDecodeInput<AA>
71where
72 AA: ManagedTypeApi + EndpointArgumentApi,
73{
74 type NestedBuffer = ManagedBufferNestedDecodeInput<AA>;
75
76 #[inline]
77 fn byte_len(&self) -> usize {
78 AA::argument_api_impl().get_argument_len(self.arg_index)
79 }
80
81 #[inline]
82 fn into_boxed_slice_u8(self) -> Box<[u8]> {
83 AA::argument_api_impl()
84 .get_argument_boxed_bytes(self.arg_index)
85 .into_box()
86 }
87
88 #[inline]
89 fn into_max_size_buffer<H, const MAX_LEN: usize>(
90 self,
91 buffer: &mut [u8; MAX_LEN],
92 h: H,
93 ) -> Result<&[u8], H::HandledErr>
94 where
95 H: DecodeErrorHandler,
96 {
97 self.to_managed_buffer().into_max_size_buffer(buffer, h)
98 }
99
100 #[inline]
101 fn into_max_size_buffer_align_right<H, const MAX_LEN: usize>(
102 self,
103 buffer: &mut [u8; MAX_LEN],
104 h: H,
105 ) -> Result<usize, H::HandledErr>
106 where
107 H: DecodeErrorHandler,
108 {
109 self.to_managed_buffer()
110 .into_max_size_buffer_align_right(buffer, h)
111 }
112
113 #[inline]
114 fn into_u64<H>(self, _h: H) -> Result<u64, H::HandledErr>
115 where
116 H: DecodeErrorHandler,
117 {
118 Ok(AA::argument_api_impl().get_argument_u64(self.arg_index))
119 }
120
121 #[inline]
122 fn into_i64<H>(self, _h: H) -> Result<i64, H::HandledErr>
123 where
124 H: DecodeErrorHandler,
125 {
126 Ok(AA::argument_api_impl().get_argument_i64(self.arg_index))
127 }
128
129 #[inline]
130 fn supports_specialized_type<T: TryStaticCast>() -> bool {
131 T::type_eq::<ManagedBuffer<AA>>()
132 || T::type_eq::<BigUint<AA>>()
133 || T::type_eq::<BigInt<AA>>()
134 }
135
136 #[inline]
137 fn into_specialized<T, H>(self, h: H) -> Result<T, H::HandledErr>
138 where
139 T: TryStaticCast,
140 H: DecodeErrorHandler,
141 {
142 if let Some(result) = try_execute_then_cast(|| self.to_managed_buffer()) {
143 Ok(result)
144 } else if let Some(result) = try_execute_then_cast(|| self.to_big_uint()) {
145 Ok(result)
146 } else if let Some(result) = try_execute_then_cast(|| self.to_big_int()) {
147 Ok(result)
148 } else {
149 Err(h.handle_error(DecodeError::UNSUPPORTED_OPERATION))
150 }
151 }
152
153 #[inline]
154 fn into_nested_buffer(self) -> Self::NestedBuffer {
155 ManagedBufferNestedDecodeInput::new(self.to_managed_buffer())
156 }
157}