Skip to content

Commit

Permalink
AnnotatedValue refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
andrei-marinica committed Mar 27, 2024
1 parent 8f96dde commit 09521e4
Show file tree
Hide file tree
Showing 21 changed files with 181 additions and 197 deletions.
104 changes: 95 additions & 9 deletions framework/base/src/types/interaction/annotated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,31 @@ use crate::types::{heap::Address, BigUint, ManagedAddress, ManagedBuffer};

use super::TxEnv;

pub trait AnnotatedValue<Env, T>
pub trait AnnotatedValue<Env, T>: Sized
where
Env: TxEnv,
{
fn annotation(&self, env: &Env) -> ManagedBuffer<Env::Api>;

fn into_value(self, env: &Env) -> T;
/// Produces the value from a reference of the annotated type. Might involve a `.clone()` in some cases.
fn to_value(&self, env: &Env) -> T;

/// Consumes annotated value to produce actual value.
///
/// Override whenever it helps to avoid an unnecessary clone.
fn into_value(self, env: &Env) -> T {
self.to_value(env)
}

/// Can be used when working with references only.
///
/// Override whenever it helps to avoid an unnecessary clone.
fn with_value_ref<F, R>(&self, env: &Env, f: F) -> R
where
F: FnOnce(&T) -> R,
{
f(&self.to_value(env))
}
}

impl<Env> AnnotatedValue<Env, ManagedAddress<Env::Api>> for ManagedAddress<Env::Api>
Expand All @@ -19,9 +37,20 @@ where
self.hex_expr()
}

fn to_value(&self, env: &Env) -> ManagedAddress<Env::Api> {
self.clone()
}

fn into_value(self, _env: &Env) -> ManagedAddress<Env::Api> {
self
}

fn with_value_ref<F, R>(&self, env: &Env, f: F) -> R
where
F: FnOnce(&ManagedAddress<Env::Api>) -> R,
{
f(self)
}
}

impl<Env> AnnotatedValue<Env, ManagedAddress<Env::Api>> for &ManagedAddress<Env::Api>
Expand All @@ -32,9 +61,20 @@ where
self.hex_expr()
}

fn to_value(&self, env: &Env) -> ManagedAddress<Env::Api> {
(*self).clone()
}

fn into_value(self, _env: &Env) -> ManagedAddress<Env::Api> {
self.clone()
}

fn with_value_ref<F, R>(&self, env: &Env, f: F) -> R
where
F: FnOnce(&ManagedAddress<Env::Api>) -> R,
{
f(self)
}
}

impl<Env> AnnotatedValue<Env, ManagedAddress<Env::Api>> for Address
Expand All @@ -45,8 +85,8 @@ where
ManagedAddress::from(self).hex_expr()
}

fn into_value(self, _env: &Env) -> ManagedAddress<Env::Api> {
self.into()
fn to_value(&self, env: &Env) -> ManagedAddress<Env::Api> {
ManagedAddress::from(self)
}
}

Expand All @@ -58,8 +98,8 @@ where
ManagedAddress::from(*self).hex_expr()
}

fn into_value(self, _env: &Env) -> ManagedAddress<Env::Api> {
self.into()
fn to_value(&self, env: &Env) -> ManagedAddress<Env::Api> {
ManagedAddress::from(*self)
}
}

Expand All @@ -71,9 +111,20 @@ where
self.hex_expr()
}

fn to_value(&self, _env: &Env) -> ManagedBuffer<Env::Api> {
self.clone()
}

fn into_value(self, _env: &Env) -> ManagedBuffer<Env::Api> {
self
}

fn with_value_ref<F, R>(&self, env: &Env, f: F) -> R
where
F: FnOnce(&ManagedBuffer<Env::Api>) -> R,
{
f(self)
}
}

impl<Env> AnnotatedValue<Env, BigUint<Env::Api>> for BigUint<Env::Api>
Expand All @@ -84,9 +135,20 @@ where
self.to_display()
}

fn to_value(&self, _env: &Env) -> BigUint<Env::Api> {
self.clone()
}

fn into_value(self, _env: &Env) -> BigUint<Env::Api> {
self
}

fn with_value_ref<F, R>(&self, env: &Env, f: F) -> R
where
F: FnOnce(&BigUint<Env::Api>) -> R,
{
f(self)
}
}

impl<Env> AnnotatedValue<Env, BigUint<Env::Api>> for &BigUint<Env::Api>
Expand All @@ -97,20 +159,44 @@ where
self.to_display()
}

fn to_value(&self, _env: &Env) -> BigUint<Env::Api> {
(*self).clone()
}

fn into_value(self, _env: &Env) -> BigUint<Env::Api> {
self.clone()
}

fn with_value_ref<F, R>(&self, env: &Env, f: F) -> R
where
F: FnOnce(&BigUint<Env::Api>) -> R,
{
f(self)
}
}

impl<Env> AnnotatedValue<Env, BigUint<Env::Api>> for u64
where
Env: TxEnv,
{
fn annotation(&self, env: &Env) -> ManagedBuffer<Env::Api> {
self.into_value(env).to_display()
self.to_value(env).to_display()
}

fn into_value(self, _env: &Env) -> BigUint<Env::Api> {
BigUint::<Env::Api>::from(self)
fn to_value(&self, _env: &Env) -> BigUint<Env::Api> {
BigUint::from(*self)
}
}

impl<Env> AnnotatedValue<Env, BigUint<Env::Api>> for ()
where
Env: TxEnv,
{
fn annotation(&self, env: &Env) -> ManagedBuffer<Env::Api> {
ManagedBuffer::from("0")
}

fn to_value(&self, _env: &Env) -> BigUint<Env::Api> {
BigUint::zero()
}
}
17 changes: 3 additions & 14 deletions framework/base/src/types/interaction/expr/address_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ where
result
}

fn into_value(self, _env: &Env) -> ManagedAddress<Env::Api> {
fn to_value(&self, _env: &Env) -> ManagedAddress<Env::Api> {
let expr: [u8; 32] = self.eval_to_array();
expr.into()
}
}

impl<Env> TxFrom<Env> for AddressExpr
where
Env: TxEnv,
Expand All @@ -36,19 +37,7 @@ where
}
impl<Env> TxFromSpecified<Env> for AddressExpr where Env: TxEnv {}
impl<Env> TxTo<Env> for AddressExpr where Env: TxEnv {}
impl<Env> TxToSpecified<Env> for AddressExpr
where
Env: TxEnv,
{
fn with_address_ref<F, R>(&self, _env: &Env, f: F) -> R
where
F: FnOnce(&ManagedAddress<Env::Api>) -> R,
{
let expr: [u8; 32] = self.eval_to_array();
let ma = expr.into();
f(&ma)
}
}
impl<Env> TxToSpecified<Env> for AddressExpr where Env: TxEnv {}

impl AddressExpr {
pub const fn eval_to_array(&self) -> [u8; 32] {
Expand Down
17 changes: 3 additions & 14 deletions framework/base/src/types/interaction/expr/sc_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ where
result
}

fn into_value(self, _env: &Env) -> ManagedAddress<Env::Api> {
fn to_value(&self, _env: &Env) -> ManagedAddress<Env::Api> {
let expr: [u8; 32] = self.eval_to_array();
expr.into()
}
}

impl<'a, Env> TxFrom<Env> for ScExpr<'a>
where
Env: TxEnv,
Expand All @@ -38,19 +39,7 @@ where
}
impl<'a, Env> TxFromSpecified<Env> for ScExpr<'a> where Env: TxEnv {}
impl<'a, Env> TxTo<Env> for ScExpr<'a> where Env: TxEnv {}
impl<'a, Env> TxToSpecified<Env> for ScExpr<'a>
where
Env: TxEnv,
{
fn with_address_ref<F, R>(&self, _env: &Env, f: F) -> R
where
F: FnOnce(&ManagedAddress<Env::Api>) -> R,
{
let expr: [u8; 32] = self.eval_to_array();
let ma = expr.into();
f(&ma)
}
}
impl<'a, Env> TxToSpecified<Env> for ScExpr<'a> where Env: TxEnv {}

impl<'a> ScExpr<'a> {
pub const fn eval_to_array(&self) -> [u8; 32] {
Expand Down
4 changes: 2 additions & 2 deletions framework/base/src/types/interaction/tx_call_deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ where
fn execute_deploy_raw(self) -> (ManagedAddress<Api>, ManagedVec<Api, ManagedBuffer<Api>>, RH) {
let gas_limit = self.gas.resolve_gas(&self.env);

let (new_address, raw_results) = self.payment.with_egld_value(|egld_value| {
let (new_address, raw_results) = self.payment.with_egld_value(&self.env, |egld_value| {
SendRawWrapper::<Api>::new().deploy_contract(
gas_limit,
egld_value,
Expand Down Expand Up @@ -71,7 +71,7 @@ where
) -> (ManagedAddress<Api>, ManagedVec<Api, ManagedBuffer<Api>>, RH) {
let gas_limit = self.gas.resolve_gas(&self.env);

let (new_address, raw_results) = self.payment.with_egld_value(|egld_value| {
let (new_address, raw_results) = self.payment.with_egld_value(&self.env, |egld_value| {
SendRawWrapper::<Api>::new().deploy_from_source_contract(
gas_limit,
egld_value,
Expand Down
4 changes: 2 additions & 2 deletions framework/base/src/types/interaction/tx_call_te.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ where
pub fn transfer_execute(self) {
let gas_limit: u64;
if self.data.is_no_call() {
if self.payment.is_no_payment() {
if self.payment.is_no_payment(&self.env) {
return;
} else {
gas_limit = 0;
Expand Down Expand Up @@ -54,7 +54,7 @@ where
///
/// Can only used for simple transfers.
pub fn transfer_if_not_empty(self) {
if self.payment.is_no_payment() {
if self.payment.is_no_payment(&self.env) {
return;
}

Expand Down
8 changes: 4 additions & 4 deletions framework/base/src/types/interaction/tx_call_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ where
/// TODO: change return type to `!`.
pub fn upgrade_async_call_and_exit(self) {
let gas = self.gas.explicit_or_gas_left(&self.env);
self.payment.with_egld_value(|egld_value| {
self.payment.with_egld_value(&self.env, |egld_value| {
SendRawWrapper::<Api>::new().upgrade_contract(
&self.to,
gas,
Expand Down Expand Up @@ -68,7 +68,7 @@ where
/// TODO: change return type to `!`.
pub fn upgrade_async_call_and_exit(self) {
let gas = self.gas.explicit_or_gas_left(&self.env);
self.payment.with_egld_value(|egld_value| {
self.payment.with_egld_value(&self.env, |egld_value| {
SendRawWrapper::<Api>::new().upgrade_from_source_contract(
&self.to,
gas,
Expand Down Expand Up @@ -98,7 +98,7 @@ where
/// If another one was previously set in the `Tx` object, that one will be ignored.
pub fn upgrade_contract(self, code: &ManagedBuffer<Api>, code_metadata: CodeMetadata) {
let gas = self.gas.explicit_or_gas_left(&self.env);
self.payment.with_egld_value(|egld_value| {
self.payment.with_egld_value(&self.env, |egld_value| {
SendRawWrapper::<Api>::new().upgrade_contract(
&self.to,
gas,
Expand All @@ -123,7 +123,7 @@ where
code_metadata: CodeMetadata,
) {
let gas = self.gas.explicit_or_gas_left(&self.env);
self.payment.with_egld_value(|egld_value| {
self.payment.with_egld_value(&self.env, |egld_value| {
SendRawWrapper::<Api>::new().upgrade_from_source_contract(
&self.to,
gas,
Expand Down
17 changes: 11 additions & 6 deletions framework/base/src/types/interaction/tx_payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ use crate::{
},
};

use super::{FunctionCall, TxEnv, TxFrom, TxToSpecified};
use super::{AnnotatedValue, FunctionCall, TxEnv, TxFrom, TxToSpecified};

/// Describes a payment that is part of a transaction.
pub trait TxPayment<Env>
where
Env: TxEnv,
{
/// Returns true if payment indicates transfer of either non-zero EGLD or ESDT amounts.
fn is_no_payment(&self) -> bool;
fn is_no_payment(&self, env: &Env) -> bool;

/// Transfer-execute calls have different APIs for different payments types.
/// This method selects between them.
Expand Down Expand Up @@ -57,15 +57,20 @@ where
}

/// Marks a payment object that only contains EGLD or nothing at all.
pub trait TxPaymentEgldOnly<Env>: TxPayment<Env>
pub trait TxPaymentEgldOnly<Env>: TxPayment<Env> + AnnotatedValue<Env, BigUint<Env::Api>>
where
Env: TxEnv,
{
fn with_egld_value<F, R>(&self, f: F) -> R
fn with_egld_value<F, R>(&self, env: &Env, f: F) -> R
where
F: FnOnce(&BigUint<Env::Api>) -> R;
F: FnOnce(&BigUint<Env::Api>) -> R,
{
self.with_value_ref(env, f)
}

fn into_egld_payment(self, env: &Env) -> BigUint<Env::Api>;
fn into_egld_payment(self, env: &Env) -> BigUint<Env::Api> {
self.into_value(env)
}
}

#[derive(Clone)]
Expand Down
Loading

0 comments on commit 09521e4

Please sign in to comment.