use core::marker::PhantomData;
use crate::{
api::{
const_handles, use_raw_handle, CallValueApi, CallValueApiImpl, ErrorApi, ErrorApiImpl,
HandleConstraints, ManagedTypeApi, StaticVarApiImpl,
},
err_msg,
types::{
BigUint, RewaOrDcdtTokenIdentifier, RewaOrDcdtTokenPayment, RewaOrMultiDcdtPayment,
DcdtTokenPayment, 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 rewa_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_rewa_handle());
if call_value_handle == const_handles::UNINITIALIZED_HANDLE {
call_value_handle = use_raw_handle(const_handles::CALL_VALUE_REWA);
A::static_var_api_impl().set_call_value_rewa_handle(call_value_handle.get_raw_handle());
A::call_value_api_impl().load_rewa_value(call_value_handle.clone());
}
unsafe { ManagedRef::wrap_handle(call_value_handle) }
}
pub fn all_dcdt_transfers(&self) -> ManagedRef<'static, A, ManagedVec<A, DcdtTokenPayment<A>>> {
let mut call_value_handle: A::ManagedBufferHandle =
use_raw_handle(A::static_var_api_impl().get_call_value_multi_dcdt_handle());
if call_value_handle == const_handles::UNINITIALIZED_HANDLE {
call_value_handle = use_raw_handle(const_handles::CALL_VALUE_MULTI_DCDT);
A::static_var_api_impl()
.set_call_value_multi_dcdt_handle(call_value_handle.get_raw_handle());
A::call_value_api_impl().load_all_dcdt_transfers(call_value_handle.clone());
}
unsafe { ManagedRef::wrap_handle(call_value_handle) }
}
pub fn multi_dcdt<const N: usize>(&self) -> [DcdtTokenPayment<A>; N] {
self.all_dcdt_transfers()
.to_array_of_refs::<N>()
.unwrap_or_else(|| {
A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_DCDT_TRANSFERS.as_bytes())
})
}
pub fn single_dcdt(&self) -> DcdtTokenPayment<A> {
let [payments] = self.multi_dcdt();
payments
}
pub fn single_fungible_dcdt(&self) -> (TokenIdentifier<A>, BigUint<A>) {
let payment = self.single_dcdt();
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 rewa_or_single_dcdt(&self) -> RewaOrDcdtTokenPayment<A> {
let dcdt_transfers = self.all_dcdt_transfers();
match dcdt_transfers.len() {
0 => RewaOrDcdtTokenPayment {
token_identifier: RewaOrDcdtTokenIdentifier::rewa(),
token_nonce: 0,
amount: self.rewa_value().clone_value(),
},
1 => dcdt_transfers.get(0).into(),
_ => A::error_api_impl().signal_error(err_msg::INCORRECT_NUM_DCDT_TRANSFERS.as_bytes()),
}
}
pub fn rewa_or_single_fungible_dcdt(&self) -> (RewaOrDcdtTokenIdentifier<A>, BigUint<A>) {
let payment = self.rewa_or_single_dcdt();
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) -> RewaOrMultiDcdtPayment<A> {
let dcdt_transfers = self.all_dcdt_transfers();
if dcdt_transfers.is_empty() {
RewaOrMultiDcdtPayment::Rewa(self.rewa_value().clone_value())
} else {
RewaOrMultiDcdtPayment::MultiDcdt(dcdt_transfers.clone_value())
}
}
}