use core::marker::PhantomData;
use crate::{
api::{
const_handles, use_raw_handle, CallValueApi, CallValueApiImpl, ErrorApi, ErrorApiImpl,
HandleConstraints, ManagedTypeApi, StaticVarApiImpl,
},
err_msg,
types::{
BigUint, MoaxOrDctTokenIdentifier, MoaxOrDctTokenPayment, MoaxOrMultiDctPayment,
DctTokenPayment, ManagedRef, ManagedVec, TokenIdentifier,
},
};
#[derive(Default)]
pub struct CallValueWrapper<A>
where
A: CallValueApi + ErrorApi + ManagedTypeApi,
{
_phantom: PhantomData<A>,
}
impl<A> CallValueWrapper<A>
where
A: CallValueApi + ErrorApi + ManagedTypeApi,
{
pub fn new() -> Self {
CallValueWrapper {
_phantom: PhantomData,
}
}
pub fn moax_value(&self) -> ManagedRef<'static, A, BigUint<A>> {
let mut call_value_handle: A::BigIntHandle =
use_raw_handle(A::static_var_api_impl().get_call_value_moax_handle());
if call_value_handle == const_handles::UNINITIALIZED_HANDLE {
call_value_handle = use_raw_handle(const_handles::CALL_VALUE_MOAX);
A::static_var_api_impl().set_call_value_moax_handle(call_value_handle.get_raw_handle());
A::call_value_api_impl().load_moax_value(call_value_handle.clone());
}
unsafe { ManagedRef::wrap_handle(call_value_handle) }
}
pub fn all_dct_transfers(&self) -> ManagedRef<'static, A, ManagedVec<A, DctTokenPayment<A>>> {
let mut call_value_handle: A::ManagedBufferHandle =
use_raw_handle(A::static_var_api_impl().get_call_value_multi_dct_handle());
if call_value_handle == const_handles::UNINITIALIZED_HANDLE {
call_value_handle = use_raw_handle(const_handles::CALL_VALUE_MULTI_DCT);
A::static_var_api_impl()
.set_call_value_multi_dct_handle(call_value_handle.get_raw_handle());
A::call_value_api_impl().load_all_dct_transfers(call_value_handle.clone());
}
unsafe { ManagedRef::wrap_handle(call_value_handle) }
}
pub fn multi_dct<const N: usize>(&self) -> [DctTokenPayment<A>; N] {
self.all_dct_transfers()
.to_array_of_refs::<N>()
.unwrap_or_else(|| {
A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_DCT_TRANSFERS.as_bytes())
})
}
pub fn single_dct(&self) -> DctTokenPayment<A> {
let [payments] = self.multi_dct();
payments
}
pub fn single_fungible_dct(&self) -> (TokenIdentifier<A>, BigUint<A>) {
let payment = self.single_dct();
if payment.token_nonce != 0 {
A::error_api_impl().signal_error(err_msg::FUNGIBLE_TOKEN_EXPECTED_ERR_MSG.as_bytes());
}
(payment.token_identifier, payment.amount)
}
pub fn moax_or_single_dct(&self) -> MoaxOrDctTokenPayment<A> {
let dct_transfers = self.all_dct_transfers();
match dct_transfers.len() {
0 => MoaxOrDctTokenPayment {
token_identifier: MoaxOrDctTokenIdentifier::moax(),
token_nonce: 0,
amount: self.moax_value().clone_value(),
},
1 => dct_transfers.get(0).into(),
_ => A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_DCT_TRANSFERS.as_bytes()),
}
}
pub fn moax_or_single_fungible_dct(&self) -> (MoaxOrDctTokenIdentifier<A>, BigUint<A>) {
let payment = self.moax_or_single_dct();
if payment.token_nonce != 0 {
A::error_api_impl().signal_error(err_msg::FUNGIBLE_TOKEN_EXPECTED_ERR_MSG.as_bytes());
}
(payment.token_identifier, payment.amount)
}
pub fn any_payment(&self) -> MoaxOrMultiDctPayment<A> {
let dct_transfers = self.all_dct_transfers();
if dct_transfers.is_empty() {
MoaxOrMultiDctPayment::Moax(self.moax_value().clone_value())
} else {
MoaxOrMultiDctPayment::MultiDct(dct_transfers.clone_value())
}
}
}