use super::CallParams;
use crate::{
call::{
common::{
ReturnType,
Set,
Unset,
},
execution::EmptyArgumentList,
CallBuilder,
ExecutionInput,
},
Environment,
Error,
Gas,
};
use num_traits::Zero;
use pallet_contracts_uapi::CallFlags;
#[derive(Clone)]
pub struct CallV1<E: Environment> {
pub(crate) callee: E::AccountId,
pub(crate) gas_limit: Gas,
pub(crate) transferred_value: E::Balance,
pub(crate) call_flags: CallFlags,
}
impl<E: Environment> CallV1<E> {
pub fn new(callee: E::AccountId) -> Self {
Self {
callee,
gas_limit: Default::default(),
transferred_value: E::Balance::zero(),
call_flags: CallFlags::empty(),
}
}
}
impl<E> CallV1<E>
where
E: Environment,
{
pub fn gas_limit(self, gas_limit: Gas) -> Self {
CallV1 { gas_limit, ..self }
}
pub fn transferred_value(self, transferred_value: E::Balance) -> Self {
CallV1 {
transferred_value,
..self
}
}
}
impl<E, Args, RetType> CallBuilder<E, Set<CallV1<E>>, Args, RetType>
where
E: Environment,
{
pub fn gas_limit(self, gas_limit: Gas) -> Self {
let call_type = self.call_type.value();
CallBuilder {
call_type: Set(CallV1 {
callee: call_type.callee,
gas_limit,
transferred_value: call_type.transferred_value,
call_flags: call_type.call_flags,
}),
exec_input: self.exec_input,
return_type: self.return_type,
_phantom: Default::default(),
}
}
pub fn transferred_value(self, transferred_value: E::Balance) -> Self {
let call_type = self.call_type.value();
CallBuilder {
call_type: Set(CallV1 {
callee: call_type.callee,
gas_limit: call_type.gas_limit,
transferred_value,
call_flags: call_type.call_flags,
}),
exec_input: self.exec_input,
return_type: self.return_type,
_phantom: Default::default(),
}
}
#[inline]
#[must_use]
pub fn call_flags(self, call_flags: CallFlags) -> Self {
let call_type = self.call_type.value();
CallBuilder {
call_type: Set(CallV1 {
callee: call_type.callee,
gas_limit: call_type.gas_limit,
transferred_value: call_type.transferred_value,
call_flags,
}),
exec_input: self.exec_input,
return_type: self.return_type,
_phantom: Default::default(),
}
}
}
impl<E, Args, RetType>
CallBuilder<E, Set<CallV1<E>>, Set<ExecutionInput<Args>>, Set<ReturnType<RetType>>>
where
E: Environment,
{
pub fn params(self) -> CallParams<E, CallV1<E>, Args, RetType> {
CallParams {
call_type: self.call_type.value(),
_return_type: Default::default(),
exec_input: self.exec_input.value(),
_phantom: self._phantom,
}
}
}
impl<E, RetType>
CallBuilder<
E,
Set<CallV1<E>>,
Unset<ExecutionInput<EmptyArgumentList>>,
Unset<RetType>,
>
where
E: Environment,
{
pub fn params(self) -> CallParams<E, CallV1<E>, EmptyArgumentList, ()> {
CallParams {
call_type: self.call_type.value(),
_return_type: Default::default(),
exec_input: Default::default(),
_phantom: self._phantom,
}
}
}
impl<E>
CallBuilder<
E,
Set<CallV1<E>>,
Unset<ExecutionInput<EmptyArgumentList>>,
Unset<ReturnType<()>>,
>
where
E: Environment,
{
pub fn invoke(self) {
self.params().invoke()
}
pub fn try_invoke(self) -> Result<ink_primitives::MessageResult<()>, Error> {
self.params().try_invoke()
}
}
impl<E, Args, R>
CallBuilder<E, Set<CallV1<E>>, Set<ExecutionInput<Args>>, Set<ReturnType<R>>>
where
E: Environment,
Args: scale::Encode,
R: scale::Decode,
{
pub fn invoke(self) -> R {
self.params().invoke()
}
pub fn try_invoke(self) -> Result<ink_primitives::MessageResult<R>, Error> {
self.params().try_invoke()
}
}
impl<E, Args, R> CallParams<E, CallV1<E>, Args, R>
where
E: Environment,
{
#[inline]
pub fn callee(&self) -> &E::AccountId {
&self.call_type.callee
}
#[inline]
pub fn gas_limit(&self) -> Gas {
self.call_type.gas_limit
}
#[inline]
pub fn transferred_value(&self) -> &E::Balance {
&self.call_type.transferred_value
}
#[inline]
pub fn call_flags(&self) -> &CallFlags {
&self.call_type.call_flags
}
}
impl<E, Args, R> CallParams<E, CallV1<E>, Args, R>
where
E: Environment,
Args: scale::Encode,
R: scale::Decode,
{
pub fn invoke(&self) -> R {
crate::invoke_contract_v1(self)
.unwrap_or_else(|env_error| {
panic!("Cross-contract call failed with {env_error:?}")
})
.unwrap_or_else(|lang_error| {
panic!("Cross-contract call failed with {lang_error:?}")
})
}
pub fn try_invoke(&self) -> Result<ink_primitives::MessageResult<R>, crate::Error> {
crate::invoke_contract_v1(self)
}
}