Repository: MystenLabs/sui
File: crates/sui-indexer-alt-graphql/src/api/types/transaction_kind/programmable/inputs/balance_withdraw.rs (Rust)

Code before:
pub struct BalanceWithdraw {
    pub reservation: Option<WithdrawalReservation>,

    /// The type of the funds accumulator to withdraw from (e.g. `0x2::balance::Balance<0x2::sui::SUI>`).
    pub type_arg: Option<MoveType>,

    pub withdraw_from: Option<WithdrawFrom>,
}

/// Reservation details for a withdrawal.
#[derive(Union, Clone)]
pub enum WithdrawalReservation {
    EntireBalance(EntireBalance),
    MaxAmountU64(MaxAmountU64),
}

#[derive(SimpleObject, Clone)]
pub struct EntireBalance {
    /// Placeholder field.
    #[graphql(name = "_")]
    pub dummy: Option<bool>,
}

#[derive(SimpleObject, Clone)]
pub struct MaxAmountU64 {
    pub amount: Option<UInt53>,
}

#[derive(Enum, Copy, Clone, Eq, PartialEq)]
pub enum WithdrawFrom {
    Sender,
    Sponsor,
}

impl BalanceWithdraw {
    pub fn from_native(withdrawal: NativeFundsWithdrawalArg, scope: Scope) -> Self {
        let NativeFundsWithdrawalArg {
            reservation,
            type_arg,
            withdraw_from,
        } = withdrawal;

        let reservation = Some(match reservation {
            NativeReservation::EntireBalance => {
                WithdrawalReservation::EntireBalance(EntireBalance { dummy: None })
            }
            NativeReservation::MaxAmountU64(amount) => {
                WithdrawalReservation::MaxAmountU64(MaxAmountU64 {
                    amount: Some(amount.into()),
                })
            }

Review comment (suggestion):
We can only use `UInt53` when we can guarantee the value fits into 53 bits, so we have to use `BigInt` here, as it could be an arbitrary `u64`.

```suggestion
    pub amount: Option<BigInt>,
```

Code after:
use crate::api::scalars::big_int::BigInt;
use crate::api::types::move_type::MoveType;
use crate::scope::Scope;

/// Input for withdrawing funds from an accumulator.
#[derive(SimpleObject, Clone)]
pub struct BalanceWithdraw {
    /// How much to withdraw from the accumulator.
    pub reservation: Option<WithdrawalReservation>,

    /// The type of the funds accumulator to withdraw from (e.g. `0x2::balance::Balance<0x2::sui::SUI>`).
    #[graphql(name = "type")]
    pub type_: Option<MoveType>,

    /// The account to withdraw funds from.
    pub withdraw_from: Option<WithdrawFrom>,
}

/// Reservation details for a withdrawal.
#[derive(Union, Clone)]
pub enum WithdrawalReservation {
    MaxAmountU64(WithdrawMaxAmountU64),
}

#[derive(SimpleObject, Clone)]
pub struct WithdrawMaxAmountU64 {
    pub amount: Option<BigInt>,
}

/// The account to withdraw funds from.
#[derive(Enum, Copy, Clone, Eq, PartialEq)]
pub enum WithdrawFrom {
    /// The funds are withdrawn from the transaction sender's account.
    Sender,
    /// The funds are withdrawn from the sponsor's account.
    Sponsor,
}

impl BalanceWithdraw {
    pub fn from_native(withdrawal: NativeFundsWithdrawalArg, scope: Scope) -> Self {
        let NativeFundsWithdrawalArg {
            reservation,
            type_arg,
            withdraw_from,
        } = withdrawal;

        let reservation = Some(match reservation {
            NativeReservation::MaxAmountU64(amount) => {
                WithdrawalReservation::MaxAmountU64(WithdrawMaxAmountU64 {
                    amount: Some(amount.into()),
                })