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
use crate::*;
use core::marker::PhantomData;
use elrond_codec::TopDecodeInput;

/// Adapter from the API to the TopDecodeInput trait.
/// Allows objects to be deserialized directly from the API as arguments.
///
/// Of course the implementation provides shortcut deserialization computation paths directly from API:
/// into_u64, into_i64, ...
///
/// This is a performance-critical struct.
/// Since the wasm ContractIOApi is zero-size,
/// it means that this structures translates to a single glorified i32 in wasm.
pub struct ArgDecodeInput<A, BigInt, BigUint>
where
	BigUint: BigUintApi + 'static,
	BigInt: BigIntApi<BigUint> + 'static,
	A: ContractIOApi<BigInt, BigUint>,
{
	api: A,
	arg_index: i32,
	_phantom1: PhantomData<BigInt>,
	_phantom2: PhantomData<BigUint>,
}

impl<A, BigInt, BigUint> ArgDecodeInput<A, BigInt, BigUint>
where
	BigUint: BigUintApi + 'static,
	BigInt: BigIntApi<BigUint> + 'static,
	A: ContractIOApi<BigInt, BigUint>,
{
	#[inline]
	pub fn new(api: A, arg_index: i32) -> Self {
		ArgDecodeInput {
			api,
			arg_index,
			_phantom1: PhantomData,
			_phantom2: PhantomData,
		}
	}
}

impl<A, BigInt, BigUint> TopDecodeInput for ArgDecodeInput<A, BigInt, BigUint>
where
	BigUint: BigUintApi + 'static,
	BigInt: BigIntApi<BigUint> + 'static,
	A: ContractIOApi<BigInt, BigUint>,
{
	fn byte_len(&self) -> usize {
		self.api.get_argument_len(self.arg_index)
	}

	fn into_boxed_slice_u8(self) -> Box<[u8]> {
		self.api.get_argument_boxed_bytes(self.arg_index).into_box()
	}

	fn into_u64(self) -> u64 {
		self.api.get_argument_u64(self.arg_index)
	}

	fn into_i64(self) -> i64 {
		self.api.get_argument_i64(self.arg_index)
	}

	#[inline]
	fn try_get_big_uint_handle(&self) -> (bool, i32) {
		(true, self.api.get_argument_big_uint_raw(self.arg_index))
	}

	#[inline]
	fn try_get_big_int_handle(&self) -> (bool, i32) {
		(true, self.api.get_argument_big_int_raw(self.arg_index))
	}
}