1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use crate::*;
use elrond_codec::*;
use core::marker::PhantomData;
pub fn load_single_arg<A, BigInt, BigUint, T>(api: &A, index: i32, arg_id: ArgId) -> T
where
T: Decode,
BigUint: BigUintApi + 'static,
BigInt: BigIntApi<BigUint> + 'static,
A: ContractIOApi<BigInt, BigUint> + 'static
{
match T::TYPE_INFO {
TypeInfo::BigInt => {
let big_int_arg = api.get_argument_big_int(index);
let cast_big_int: T = unsafe { core::mem::transmute_copy(&big_int_arg) };
cast_big_int
},
TypeInfo::BigUint => {
let big_uint_arg = api.get_argument_big_uint(index);
let cast_big_uint: T = unsafe { core::mem::transmute_copy(&big_uint_arg) };
cast_big_uint
},
_ => {
if let Some(res_i64) = T::top_decode_from_i64(|| api.get_argument_i64(index)) {
match res_i64 {
Ok(from_i64) => from_i64,
Err(de_err) => {
let mut decode_err_message: Vec<u8> = Vec::new();
decode_err_message.extend_from_slice(err_msg::ARG_DECODE_ERROR_1);
decode_err_message.extend_from_slice(arg_id);
decode_err_message.extend_from_slice(err_msg::ARG_DECODE_ERROR_2);
decode_err_message.extend_from_slice(de_err.message_bytes());
api.signal_error(decode_err_message.as_slice())
}
}
} else {
let arg_bytes = api.get_argument_vec(index);
match elrond_codec::decode_from_byte_slice(arg_bytes.as_slice()) {
Ok(v) => v,
Err(de_err) => {
let mut decode_err_message: Vec<u8> = Vec::new();
decode_err_message.extend_from_slice(err_msg::ARG_DECODE_ERROR_1);
decode_err_message.extend_from_slice(arg_id);
decode_err_message.extend_from_slice(err_msg::ARG_DECODE_ERROR_2);
decode_err_message.extend_from_slice(de_err.message_bytes());
api.signal_error(decode_err_message.as_slice())
}
}
}
}
}
}
pub struct DynEndpointArgLoader<'a, A, BigInt, BigUint>
where
BigUint: BigUintApi + 'static,
BigInt: BigIntApi<BigUint> + 'static,
A: ContractIOApi<BigInt, BigUint> + 'a
{
api: &'a A,
current_index: i32,
num_arguments: i32,
_phantom1: PhantomData<BigInt>,
_phantom2: PhantomData<BigUint>,
}
impl<'a, A, BigInt, BigUint> DynEndpointArgLoader<'a, A, BigInt, BigUint>
where
BigUint: BigUintApi + 'static,
BigInt: BigIntApi<BigUint> + 'static,
A: ContractIOApi<BigInt, BigUint> + 'a
{
pub fn new(api: &'a A) -> Self {
DynEndpointArgLoader {
api,
current_index : 0,
num_arguments: api.get_num_arguments(),
_phantom1: PhantomData,
_phantom2: PhantomData,
}
}
}
impl<'a, A, BigInt, BigUint, T> DynArgLoader<T> for DynEndpointArgLoader<'a, A, BigInt, BigUint>
where
T: Decode,
BigUint: BigUintApi + 'static,
BigInt: BigIntApi<BigUint> + 'static,
A: ContractIOApi<BigInt, BigUint> + 'static
{
#[inline]
fn has_next(&self) -> bool {
self.current_index < self.num_arguments
}
fn next_arg(&mut self, arg_id: ArgId) -> Result<Option<T>, SCError> {
if self.current_index >= self.num_arguments {
Ok(None)
} else {
let arg: T = load_single_arg(self.api, self.current_index, arg_id);
self.current_index += 1;
Ok(Some(arg))
}
}
}